diff --git a/.gitignore b/.gitignore
index d62f537c..0af7cb4e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,6 +15,8 @@ public/stylesheets/cache
tmp
vendor/plugins/query_trace/
rerun.txt
-public/javascripts/jquery-all.js
-public/javascripts/tracks.js
-public/stylesheets/all.css
+public/javascripts/jquery-cached.js
+public/javascripts/tracks-cached.js
+public/stylesheets/tracks-cached.css
+.idea
+.rvmrc
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index e94aac3a..779f9031 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -33,10 +33,12 @@ class ApplicationController < ActionController::Base
before_filter :set_session_expiration
before_filter :set_time_zone
before_filter :set_zindex_counter
+ before_filter :set_locale
prepend_before_filter :login_required
prepend_before_filter :enable_mobile_content_negotiation
+ # after_filter :set_locale
after_filter :set_charset
-
+
include ActionView::Helpers::TextHelper
include ActionView::Helpers::SanitizeHelper
extend ActionView::Helpers::SanitizeHelper::ClassMethods
@@ -47,6 +49,14 @@ class ApplicationController < ActionController::Base
headers["Content-Type"] ||= "text/html; charset=UTF-8"
end
+ def set_locale
+ locale = params[:locale] # specifying a locale in the request takes precedence
+ locale = locale || prefs.locale unless current_user.nil? # otherwise, the locale of the currently logged in user takes over
+ locale = locale || request.env['HTTP_ACCEPT_LANGUAGE'].scan(/^[a-z]{2}/).first if request.env['HTTP_ACCEPT_LANGUAGE']
+ I18n.locale = locale.nil? ? I18n.default_locale : (I18n::available_locales.include?(locale.to_sym) ? locale : I18n.default_locale)
+ logger.debug("Selected '#{I18n.locale}' as locale")
+ end
+
def set_session_expiration
# http://wiki.rubyonrails.com/rails/show/HowtoChangeSessionOptions
unless session == nil
@@ -114,21 +124,25 @@ class ApplicationController < ActionController::Base
# config/settings.yml
#
def format_date(date)
- if date
- date_format = prefs.date_format
- formatted_date = date.in_time_zone(prefs.time_zone).strftime("#{date_format}")
- else
- formatted_date = ''
- end
- formatted_date
+ return date ? date.in_time_zone(prefs.time_zone).strftime("#{prefs.date_format}") : ''
end
-
def for_autocomplete(coll, substr)
- filtered = coll.find_all{|item| item.name.downcase.include? substr.downcase}
- return filtered.map {|item| "#{item.name}|#{item.id}"}.join("\n")
+ if substr # protect agains empty request
+ filtered = coll.find_all{|item| item.name.downcase.include? substr.downcase}
+ json_elems = "[{" + filtered.map {|item| "\"value\" : \"#{item.name}\", \"id\" : \"#{item.id}\""}.join("},{") + "}]"
+ return json_elems == "[{}]" ? "" : json_elems
+ else
+ return ""
+ end
end
+ def auto_complete_result2(entries, phrase = nil)
+ json_elems = "[{" + entries.map {|item| "\"id\" : \"#{item.id}\", \"value\" : \"#{item.specification()}\""}.join("},{") + "}]"
+ return json_elems == "[{}]" ? "" : json_elems
+ end
+
+
# Uses RedCloth to transform text using either Textile or Markdown Need to
# require redcloth above RedCloth 3.0 or greater is needed to use Markdown,
# otherwise it only handles Textile
@@ -196,7 +210,7 @@ class ApplicationController < ActionController::Base
def admin_login_required
unless User.find_by_id_and_is_admin(session['user_id'], true)
- render :text => "401 Unauthorized: Only admin users are allowed access to this function.", :status => 401
+ render :text => t('errors.user_unauthorized'), :status => 401
return false
end
end
diff --git a/app/controllers/contexts_controller.rb b/app/controllers/contexts_controller.rb
index 8365c320..6e6cd265 100644
--- a/app/controllers/contexts_controller.rb
+++ b/app/controllers/contexts_controller.rb
@@ -13,16 +13,25 @@ class ContextsController < ApplicationController
# checks later don't result in separate SQL queries
@active_contexts = current_user.contexts.active(true)
@hidden_contexts = current_user.contexts.hidden(true)
- @count = @active_contexts.size + @hidden_contexts.size
+ @new_context = current_user.contexts.build
+
+ # save all contexts here as @new_context will add an empty one to current_user.contexts
+ @all_contexts = @active_contexts + @hidden_contexts
+ @count = @all_contexts.size
+
+
init_not_done_counts(['context'])
respond_to do |format|
format.html &render_contexts_html
format.m &render_contexts_mobile
- format.xml { render :xml => current_user.contexts.to_xml( :except => :user_id ) }
+ format.xml { render :xml => @all_contexts.to_xml( :except => :user_id ) }
format.rss &render_contexts_rss_feed
format.atom &render_contexts_atom_feed
- format.text { render :action => 'index', :layout => false, :content_type => Mime::TEXT }
- format.autocomplete { render :text => for_autocomplete(@active_contexts + @hidden_contexts, params[:q])}
+ format.text do
+ @all_contexts = current_user.contexts.all
+ render :action => 'index', :layout => false, :content_type => Mime::TEXT
+ end
+ format.autocomplete { render :text => for_autocomplete(@active_contexts + @hidden_contexts, params[:term])}
end
end
@@ -90,13 +99,18 @@ class ContextsController < ApplicationController
@original_context_hidden = @context.hidden?
@context.attributes = params["context"]
- if @context.save
+ @saved = @context.save
+
+ if @saved
if boolean_param('wants_render')
- @context_state_changed = (@original_context_hidden != @context.hidden?)
- @new_state = (@context.hidden? ? "hidden" : "active") if @context_state_changed
+ @state_changed = (@original_context_hidden != @context.hidden?)
+ @new_state = (@context.hidden? ? "hidden" : "active") if @state_changed
respond_to do |format|
format.js
end
+
+ # TODO is this param ever used? is this dead code?
+
elsif boolean_param('update_context_name')
@contexts = current_user.projects
render :template => 'contexts/update_context_name.js.rjs'
@@ -105,8 +119,9 @@ class ContextsController < ApplicationController
render :text => success_text || 'Success'
end
else
- notify :warning, "Couldn't update new context"
- render :text => ""
+ respond_to do |format|
+ format.js
+ end
end
end
@@ -126,7 +141,10 @@ class ContextsController < ApplicationController
@context.destroy
respond_to do |format|
- format.js { @down_count = current_user.contexts.size }
+ format.js do
+ @down_count = current_user.contexts.size
+ update_state_counts
+ end
format.xml { render :text => "Deleted context #{@context.name}" }
end
end
@@ -144,6 +162,13 @@ class ContextsController < ApplicationController
protected
+ def update_state_counts
+ @active_contexts_count = current_user.contexts.active.count
+ @hidden_contexts_count = current_user.contexts.hidden.count
+ @show_active_contexts = @active_contexts_count > 0
+ @show_hidden_contexts = @hidden_contexts_count > 0
+ end
+
def render_contexts_html
lambda do
@page_title = "TRACKS::List Contexts"
@@ -179,14 +204,14 @@ class ContextsController < ApplicationController
def render_contexts_rss_feed
lambda do
- render_rss_feed_for current_user.contexts, :feed => feed_options,
+ render_rss_feed_for current_user.contexts.all, :feed => feed_options,
:item => { :description => lambda { |c| c.summary(count_undone_todos_phrase(c)) } }
end
end
def render_contexts_atom_feed
lambda do
- render_atom_feed_for current_user.contexts, :feed => feed_options,
+ render_atom_feed_for current_user.contexts.all, :feed => feed_options,
:item => { :description => lambda { |c| c.summary(count_undone_todos_phrase(c)) },
:author => lambda { |c| nil } }
end
@@ -230,6 +255,7 @@ class ContextsController < ApplicationController
@count = @not_done_todos.size
end
+
end
end
diff --git a/app/controllers/feedlist_controller.rb b/app/controllers/feedlist_controller.rb
index 4c2924e9..16d1ddc7 100644
--- a/app/controllers/feedlist_controller.rb
+++ b/app/controllers/feedlist_controller.rb
@@ -26,13 +26,19 @@ class FeedlistController < ApplicationController
end
def get_feeds_for_context
- context = current_user.contexts.find params[:context_id]
- render :partial => 'feed_for_context', :locals => { :context => context }
+ @context = current_user.contexts.find params[:context_id]
+ respond_to do |format|
+ format.html { render :file => 'feedlist/get_feeds_for_context'}
+ format.js
+ end
end
def get_feeds_for_project
- project = current_user.projects.find params[:project_id]
- render :partial => 'feed_for_project', :locals => { :project => project }
+ @project = current_user.projects.find params[:project_id]
+ respond_to do |format|
+ format.html { render :file => "feedlist/get_feeds_for_project"}
+ format.js
+ end
end
end
diff --git a/app/controllers/login_controller.rb b/app/controllers/login_controller.rb
index 5106686f..08ded1c9 100644
--- a/app/controllers/login_controller.rb
+++ b/app/controllers/login_controller.rb
@@ -33,30 +33,30 @@ class LoginController < ApplicationController
@page_title = "TRACKS::Login"
cookies[:preferred_auth] = prefered_auth? unless cookies[:preferred_auth]
case request.method
- when :post
- if @user = User.authenticate(params['user_login'], params['user_password'])
- session['user_id'] = @user.id
- # If checkbox on login page checked, we don't expire the session after 1 hour
- # of inactivity and we remember this user for future browser sessions
- session['noexpiry'] = params['user_noexpiry']
- msg = (should_expire_sessions?) ? "will expire after 1 hour of inactivity." : "will not expire."
- notify :notice, "Login successful: session #{msg}"
- cookies[:tracks_login] = { :value => @user.login, :expires => Time.now + 1.year, :secure => SITE_CONFIG['secure_cookies'] }
- unless should_expire_sessions?
- @user.remember_me
- cookies[:auth_token] = { :value => @user.remember_token , :expires => @user.remember_token_expires_at, :secure => SITE_CONFIG['secure_cookies'] }
- end
- redirect_back_or_home
- return
- else
- @login = params['user_login']
- notify :warning, "Login unsuccessful"
- end
- when :get
- if User.no_users_yet?
- redirect_to signup_path
- return
+ when :post
+ if @user = User.authenticate(params['user_login'], params['user_password'])
+ session['user_id'] = @user.id
+ # If checkbox on login page checked, we don't expire the session after 1 hour
+ # of inactivity and we remember this user for future browser sessions
+ session['noexpiry'] = params['user_noexpiry']
+ msg = (should_expire_sessions?) ? "will expire after 1 hour of inactivity." : "will not expire."
+ notify :notice, "Login successful: session #{msg}"
+ cookies[:tracks_login] = { :value => @user.login, :expires => Time.now + 1.year, :secure => SITE_CONFIG['secure_cookies'] }
+ unless should_expire_sessions?
+ @user.remember_me
+ cookies[:auth_token] = { :value => @user.remember_token , :expires => @user.remember_token_expires_at, :secure => SITE_CONFIG['secure_cookies'] }
end
+ redirect_back_or_home
+ return
+ else
+ @login = params['user_login']
+ notify :warning, t('login.unsuccessful')
+ end
+ when :get
+ if User.no_users_yet?
+ redirect_to signup_path
+ return
+ end
end
respond_to do |format|
format.html
@@ -73,25 +73,38 @@ class LoginController < ApplicationController
CASClient::Frameworks::Rails::Filter.logout(self)
else
reset_session
- notify :notice, "You have been logged out of Tracks."
+ notify :notice, t('login.logged_out')
redirect_to_login
end
end
+
+ def expire_session
+ # this is a hack to enable cucumber to expire a session by calling this
+ # method. The method will be unavailable for production environment
+ unless Rails.env.production?
+ session['expiry_time'] = Time.now
+ respond_to do |format|
+ format.html { render :text => "Session expired for test purposes"}
+ format.js { render :text => "" }
+ end
+ else
+ respond_to do |format|
+ format.html { render :text => "Not available for production use"}
+ format.js { render :text => "" }
+ end
+ end
+ end
def check_expiry
- # Gets called by periodically_call_remote to check whether
+ # Gets called by periodically_call_remote to check whether
# the session has timed out yet
unless session == nil
if session
return unless should_expire_sessions?
# Get expiry time (allow ten seconds window for the case where we have none)
expiry_time = session['expiry_time'] || Time.now + 10
- @time_left = expiry_time - Time.now
- if @time_left < (10*60) # Session will time out before the next check
- @msg = "Session has timed out. Please "
- else
- @msg = ""
- end
+ time_left = expiry_time - Time.now
+ @session_expired = ( time_left < (10*60) ) # Session will time out before the next check
end
end
respond_to do |format|
@@ -99,7 +112,7 @@ class LoginController < ApplicationController
end
end
- def login_cas
+ def login_cas
# If checkbox on login page checked, we don't expire the session after 1 hour
# of inactivity and we remember this user for future browser sessions
@@ -107,22 +120,21 @@ class LoginController < ApplicationController
if session[:cas_user]
if @user = User.find_by_login(session[:cas_user])
session['user_id'] = @user.id
- msg = (should_expire_sessions?) ? "will expire after 1 hour of inactivity." : "will not expire."
- notify :notice, "Login successful: session #{msg}"
+ msg = (should_expire_sessions?) ? t('login.session_will_expire', :hours => 1) : t('login.session_will_not_expire')
+ notify :notice, (t('login.successful_with_session_info') + msg)
cookies[:tracks_login] = { :value => @user.login, :expires => Time.now + 1.year, :secure => SITE_CONFIG['secure_cookies'] }
unless should_expire_sessions?
@user.remember_me
cookies[:auth_token] = { :value => @user.remember_token, :expires => @user.remember_token_expires_at, :secure => SITE_CONFIG['secure_cookies'] }
end
- #redirect_back_or_home
else
- notify :warning, "Sorry, no user by that CAS username exists (#{session[:cas_user]})"
+ notify :warning, t('login.cas_username_not_found', :username => session[:cas_user])
redirect_to signup_url ; return
end
else
notify :warning, result.message
end
- redirect_back_or_home
+ redirect_back_or_home
end
@@ -149,8 +161,8 @@ class LoginController < ApplicationController
if result.successful?
if @user = User.find_by_open_id_url(identity_url)
session['user_id'] = @user.id
- msg = (should_expire_sessions?) ? "will expire after 1 hour of inactivity." : "will not expire."
- notify :notice, "Login successful: session #{msg}"
+ msg = (should_expire_sessions?) ? t('login.session_will_expire', :hours => 1) : t('login.session_will_not_expire')
+ notify :notice, (t('login.successful_with_session_info') + msg)
cookies[:tracks_login] = { :value => @user.login, :expires => Time.now + 1.year, :secure => SITE_CONFIG['secure_cookies'] }
unless should_expire_sessions?
@user.remember_me
@@ -158,7 +170,7 @@ class LoginController < ApplicationController
end
redirect_back_or_home
else
- notify :warning, "Sorry, no user by that identity URL exists (#{identity_url})"
+ notify :warning, t('login.openid_identity_url_not_found', :identity_url => identity_url)
end
else
notify :warning, result.message
diff --git a/app/controllers/notes_controller.rb b/app/controllers/notes_controller.rb
index 329b38e5..4081611a 100644
--- a/app/controllers/notes_controller.rb
+++ b/app/controllers/notes_controller.rb
@@ -1,87 +1,72 @@
-class NotesController < ApplicationController
-
- def index
- @all_notes = current_user.notes
- @count = @all_notes.size
- @page_title = "TRACKS::All notes"
- respond_to do |format|
- format.html
- format.xml { render :xml => @all_notes.to_xml( :except => :user_id ) }
- end
- end
-
- def show
- @note = current_user.notes.find(params['id'])
- @page_title = "TRACKS::Note " + @note.id.to_s
- respond_to do |format|
- format.html
- format.m &render_note_mobile
- end
- end
-
- def render_note_mobile
- lambda do
- render :action => 'note_mobile'
- end
- end
-
- def create
- note = current_user.notes.build
- note.attributes = params["note"]
+class NotesController < ApplicationController
- saved = note.save
+ before_filter :set_source_view
+
+ def index
+ @all_notes = current_user.notes.all
+ @count = @all_notes.size
+ @page_title = "TRACKS::All notes"
+ @source_view = 'note_list'
+ respond_to do |format|
+ format.html
+ format.xml { render :xml => @all_notes.to_xml( :except => :user_id ) }
+ end
+ end
+
+ def show
+ @note = current_user.notes.find(params['id'])
+ @page_title = "TRACKS::Note " + @note.id.to_s
+ respond_to do |format|
+ format.html
+ format.m { render :action => 'note_mobile' }
+ end
+ end
+
+ def create
+ @note = current_user.notes.build
+ @note.attributes = params["note"]
+
+ @saved = @note.save
respond_to do |format|
- format.js do
- if note.save
- render :partial => 'notes_summary', :object => note
- else
- render :text => ''
- end
- end
+ format.js
format.xml do
- if saved
- head :created, :location => note_url(note), :text => "new note with id #{note.id}"
+ if @saved
+ head :created, :location => note_url(@note), :text => "new note with id #{@note.id}"
else
- render_failure note.errors.full_messages.join(', ')
+ render_failure @note.errors.full_messages.join(', ')
end
end
format.html do
render :text => 'unexpected request for html rendering'
end
end
- end
-
- def destroy
- @note = current_user.notes.find(params['id'])
-
- @note.destroy
-
- respond_to do |format|
- format.html
- format.js do
- @count = current_user.notes.size
- render
- end
- end
-
- # if note.destroy
- # render :text => ''
- # else
- # notify :warning, "Couldn't delete note \"#{note.id}\""
- # render :text => ''
- # end
- end
-
- def update
- note = current_user.notes.find(params['id'])
- note.attributes = params["note"]
- if note.save
- render :partial => 'notes', :object => note
- else
- notify :warning, "Couldn't update note \"#{note.id}\""
- render :text => ''
- end
- end
-
-end
+ end
+
+ def update
+ @note = current_user.notes.find(params['id'])
+ @note.attributes = params["note"]
+ @saved = @note.save
+ respond_to do |format|
+ format.html
+ format.js { render }
+ end
+ end
+
+ def destroy
+ @note = current_user.notes.find(params['id'])
+ @note.destroy
+
+ respond_to do |format|
+ format.html
+ format.js { @down_count = current_user.notes.size }
+ end
+ end
+
+ protected
+
+ def set_source_view
+ @source_view = params['_source_view'] || 'note'
+ end
+
+end
diff --git a/app/controllers/preferences_controller.rb b/app/controllers/preferences_controller.rb
index 89935666..db27434b 100644
--- a/app/controllers/preferences_controller.rb
+++ b/app/controllers/preferences_controller.rb
@@ -1,12 +1,13 @@
class PreferencesController < ApplicationController
def index
- @page_title = "TRACKS::Preferences"
- @prefs = prefs
+ @page_title = t('preferences.page_title')
+ @prefs = current_user.prefs
end
def edit
- @page_title = "TRACKS::Edit Preferences"
+ @page_title = t('preferences.page_title_edit')
+ @prefs = current_user.prefs
end
def update
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index 374c874c..fadf2db3 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -9,14 +9,16 @@ class ProjectsController < ApplicationController
def index
@source_view = params['_source_view'] || 'project_list'
- @projects = current_user.projects
+ @new_project = current_user.projects.build
if params[:projects_and_actions]
projects_and_actions
else
- @contexts = current_user.contexts
+ @contexts = current_user.contexts.all
init_not_done_counts(['project'])
if params[:only_active_with_no_next_actions]
@projects = current_user.projects.active.select { |p| count_undone_todos(p) == 0 }
+ else
+ @projects = current_user.projects.all
end
init_project_hidden_todo_counts(['project'])
respond_to do |format|
@@ -26,7 +28,7 @@ class ProjectsController < ApplicationController
format.rss &render_rss_feed
format.atom &render_atom_feed
format.text &render_text_feed
- format.autocomplete { render :text => for_autocomplete(@projects.reject(&:completed?), params[:q]) }
+ format.autocomplete { render :text => for_autocomplete(current_user.projects.uncompleted, params[:term]) }
end
end
end
@@ -43,9 +45,9 @@ class ProjectsController < ApplicationController
def show
@max_completed = current_user.prefs.show_number_completed
init_data_for_sidebar unless mobile?
- @page_title = "TRACKS::Project: #{@project.name}"
+ @page_title = t('projects.page_title', :project => @project.name)
- @not_done = @project.not_done_todos_including_hidden
+ @not_done = @project.todos.active_or_hidden
@deferred = @project.deferred_todos
@pending = @project.pending_todos
@done = @project.todos.find_in_state(:all, :completed, :order => "todos.completed_at DESC", :limit => current_user.prefs.show_number_completed, :include => [:context])
@@ -55,6 +57,8 @@ class ProjectsController < ApplicationController
@next_project = current_user.projects.next_from(@project)
@previous_project = current_user.projects.previous_from(@project)
@default_tags = @project.default_tags
+ @new_note = current_user.notes.new
+ @new_note.project_id = @project.id
respond_to do |format|
format.html
format.m &render_project_mobile
@@ -73,6 +77,7 @@ class ProjectsController < ApplicationController
render_failure "Expected post format is valid xml like so:
#{count_undone_todos_phrase(p)}. " - project_description += "Project is #{project.state}." + project_description += t('projects.project_state', :state => project.state) project_description += "
" project_description end diff --git a/app/controllers/recurring_todos_controller.rb b/app/controllers/recurring_todos_controller.rb index 2bfcdc3b..0d17e24b 100644 --- a/app/controllers/recurring_todos_controller.rb +++ b/app/controllers/recurring_todos_controller.rb @@ -6,15 +6,17 @@ class RecurringTodosController < ApplicationController append_before_filter :get_recurring_todo_from_param, :only => [:destroy, :toggle_check, :toggle_star, :edit, :update] def index - find_and_inactivate + @page_title = t('todos.recurring_actions_title') + find_and_inactivate @recurring_todos = current_user.recurring_todos.active @completed_recurring_todos = current_user.recurring_todos.completed + @no_recurring_todos = @recurring_todos.size == 0 @no_completed_recurring_todos = @completed_recurring_todos.size == 0 - @count = @recurring_todos.size - - @page_title = "TRACKS::Recurring Actions" + @count = @recurring_todos.size + + @new_recurring_todo = RecurringTodo.new end def new @@ -103,23 +105,24 @@ class RecurringTodosController < ApplicationController @recurring_todo.context_id = context.id end - @recurring_saved = @recurring_todo.save - unless (@recurring_saved == false) || p.tag_list.blank? + @saved = @recurring_todo.save + unless (@saved == false) || p.tag_list.blank? @recurring_todo.tag_with(p.tag_list) @recurring_todo.tags.reload end - if @recurring_saved - @message = "The recurring todo was saved" + if @saved + @status_message = "The recurring todo was saved" @todo_saved = create_todo_from_recurring_todo(@recurring_todo).nil? == false if @todo_saved - @message += " / created a new todo" + @status_message += " / created a new todo" else - @message += " / did not create todo" + @status_message += " / did not create todo" end - @count = current_user.recurring_todos.active.count + @down_count = current_user.recurring_todos.active.count + @new_recurring_todo = RecurringTodo.new else - @message = "Error saving recurring todo" + @status_message = "Error saving recurring todo" end respond_to do |format| @@ -139,7 +142,10 @@ class RecurringTodosController < ApplicationController # delete the recurring todo @saved = @recurring_todo.destroy - @remaining = current_user.recurring_todos.count + + # count remaining recurring todos + @active_remaining = current_user.recurring_todos.active.count + @completed_remaining = current_user.recurring_todos.completed.count respond_to do |format| @@ -162,11 +168,12 @@ class RecurringTodosController < ApplicationController def toggle_check @saved = @recurring_todo.toggle_completion! - @count = current_user.recurring_todos.active.count - @remaining = @count + @down_count = current_user.recurring_todos.active.count + @active_remaining = @down_count + @completed_remaining = 0 if @recurring_todo.active? - @remaining = current_user.recurring_todos.completed.count + @completed_remaining = current_user.recurring_todos.completed.count # from completed back to active -> check if there is an active todo # current_user.todos.count(:all, {:conditions => ["state = ? AND recurring_todo_id = ?", 'active',params[:id]]}) diff --git a/app/controllers/stats_controller.rb b/app/controllers/stats_controller.rb old mode 100755 new mode 100644 index 004b335c..c87ce450 --- a/app/controllers/stats_controller.rb +++ b/app/controllers/stats_controller.rb @@ -376,7 +376,7 @@ class StatsController < ApplicationController end if size==pie_cutoff - @actions_per_context[size-1]['name']='(others)' + @actions_per_context[size-1]['name']=t('stats.other_actions_label') @actions_per_context[size-1]['total']=0 @actions_per_context[size-1]['id']=-1 (size-1).upto @all_actions_per_context.size()-1 do |i| @@ -417,7 +417,7 @@ class StatsController < ApplicationController end if size==pie_cutoff - @actions_per_context[size-1]['name']='(others)' + @actions_per_context[size-1]['name']=t('stats.other_actions_label') @actions_per_context[size-1]['total']=0 @actions_per_context[size-1]['id']=-1 (size-1).upto @all_actions_per_context.size()-1 do |i| @@ -565,7 +565,7 @@ class StatsController < ApplicationController end def show_selected_actions_from_chart - @page_title = "TRACKS::Action selection" + @page_title = t('stats.action_selection_title') @count = 99 @source_view = 'stats' @@ -582,10 +582,10 @@ class StatsController < ApplicationController week_to = week_from+1 @chart_name = "actions_visible_running_time_data" - @page_title = "Actions selected from week " + @page_title = t('stats.actions_selected_from_week') @further = false if params['id'] == 'avrt_end' - @page_title += week_from.to_s + " and further" + @page_title += week_from.to_s + t('stats.actions_further') @further = true else @page_title += week_from.to_s + " - " + week_to.to_s + "" diff --git a/app/controllers/todos_controller.rb b/app/controllers/todos_controller.rb index 06a7d181..880c0de7 100644 --- a/app/controllers/todos_controller.rb +++ b/app/controllers/todos_controller.rb @@ -5,11 +5,11 @@ class TodosController < ApplicationController skip_before_filter :login_required, :only => [:index, :calendar] prepend_before_filter :login_or_feed_token_required, :only => [:index, :calendar] append_before_filter :find_and_activate_ready, :only => [:index, :list_deferred] - append_before_filter :init, :except => [ :destroy, :completed, + + # TODO: replace :except with :only + append_before_filter :init, :except => [ :tag, :tags, :destroy, :completed, :completed_archive, :check_deferred, :toggle_check, :toggle_star, - :edit, :update, :create, :calendar, :auto_complete_for_predecessor, :remove_predecessor, :add_predecessor] - append_before_filter :get_todo_from_params, :only => [ :edit, :toggle_check, :toggle_star, :show, :update, :destroy, :remove_predecessor, :show_notes] - protect_from_forgery :except => [:auto_complete_for_predecessor] + :edit, :update, :defer, :create, :calendar, :auto_complete_for_predecessor, :remove_predecessor, :add_predecessor] def index @projects = current_user.projects.find(:all, :include => [:default_context]) @@ -48,6 +48,9 @@ class TodosController < ApplicationController def create @source_view = params['_source_view'] || 'todo' + @default_context = current_user.contexts.find_by_name(params['default_context_name']) + @default_project = current_user.projects.find_by_name(params['default_project_name']) + @tag_name = params['_tag_name'] is_multiple = params[:todo] && params[:todo][:multiple_todos] && !params[:todo][:multiple_todos].nil? @@ -78,25 +81,27 @@ class TodosController < ApplicationController # Fix for #977 because AASM overrides @state on creation specified_state = @todo.state - - @todo.update_state_from_project @saved = @todo.save # Fix for #977 because AASM overrides @state on creation @todo.update_attribute('state', specified_state) unless specified_state == "immediate" + @saved = @todo.save + @todo.update_state_from_project if @saved unless (@saved == false) || tag_list.blank? @todo.tag_with(tag_list) @todo.tags.reload end - unless (@saved == false) + if @saved unless @todo.uncompleted_predecessors.empty? || @todo.state == 'project_hidden' @todo.state = 'pending' end @todo.save end + @todo.reload if @saved + respond_to do |format| format.html { redirect_to :action => "index" } format.m do @@ -110,12 +115,20 @@ class TodosController < ApplicationController end end format.js do - determine_down_count if @saved - @contexts = current_user.contexts.find(:all) if @new_context_created - @projects = current_user.projects.find(:all) if @new_project_created - @initial_context_name = params['default_context_name'] - @initial_project_name = params['default_project_name'] - @default_tags = @todo.project.default_tags unless @todo.project.nil? + if @saved + determine_down_count + @contexts = current_user.contexts.find(:all) if @new_context_created + @projects = current_user.projects.find(:all) if @new_project_created + @initial_context_name = params['default_context_name'] + @initial_project_name = params['default_project_name'] + @default_tags = @todo.project.default_tags unless @todo.project.nil? + @status_message = t('todos.added_new_next_action') + @status_message += ' ' + t('todos.to_tickler') if @todo.deferred? + @status_message += ' ' + t('todos.in_pending_state') if @todo.pending? + @status_message += ' ' + t('todos.in_hidden_state') if @todo.hidden? + @status_message = t('todos.added_new_project') + ' / ' + @status_message if @new_project_created + @status_message = t('todos.added_new_context') + ' / ' + @status_message if @new_context_created + end render :action => 'create' end format.xml do @@ -147,19 +160,19 @@ class TodosController < ApplicationController @todos = [] params[:todo][:multiple_todos].split("\n").map do |line| - @todo = current_user.todos.build( - :description => line) - @todo.project_id = @project_id - @todo.context_id = @context_id - puts "TODO: #{@todo.description}, #{@todo.project_id}, #{@todo.context_id}" - @saved = @todo.save - puts "NOT SAVED" unless @saved - unless (@saved == false) || tag_list.blank? - @todo.tag_with(tag_list) - @todo.tags.reload + unless line.blank? + @todo = current_user.todos.build( + :description => line) + @todo.project_id = @project_id + @todo.context_id = @context_id + @saved = @todo.save + unless (@saved == false) || tag_list.blank? + @todo.tag_with(tag_list) + @todo.tags.reload + end + @todos << @todo + @not_done_todos << @todo if @new_context_created end - @todos << @todo - @not_done_todos << @todo if @new_context_created end respond_to do |format| @@ -173,10 +186,15 @@ class TodosController < ApplicationController if @todos.size > 0 @default_tags = @todos[0].project.default_tags unless @todos[0].project.nil? else - @multiple_error = "You need to submit at least one next action" + @multiple_error = t('todos.next_action_needed') @saved = false; @default_tags = current_user.projects.find_by_name(@initial_project_name).default_tags unless @initial_project_name.blank? end + + @status_message = @todos.size > 1 ? t('todos.added_new_next_action_plural') : t('todos.added_new_next_action_singular') + @status_message = t('todos.added_new_project') + ' / ' + @status_message if @new_project_created + @status_message = t('todos.added_new_context') + ' / ' + @status_message if @new_context_created + render :action => 'create_multiple' end format.xml do @@ -190,8 +208,7 @@ class TodosController < ApplicationController end def edit - @projects = current_user.projects.find(:all) - @contexts = current_user.contexts.find(:all) + @todo = current_user.todos.find(params['id'], :include => [:project, :context, :tags, :taggings, :predecessors]) @source_view = params['_source_view'] || 'todo' @tag_name = params['_tag_name'] respond_to do |format| @@ -200,6 +217,7 @@ class TodosController < ApplicationController end def show + @todo = current_user.todos.find(params['id']) respond_to do |format| format.m do @projects = current_user.projects.active @@ -222,15 +240,20 @@ class TodosController < ApplicationController @todo.state = 'pending' @saved = @todo.save respond_to do |format| - format.js + format.js { + @status_message = t('todos.added_dependency', :dependency => @predecessor.description) + @status_message += t('todos.set_to_pending', :task => @todo.description) unless @original_state == 'pending' + } end end def remove_predecessor @source_view = params['_source_view'] || 'todo' + @todo = current_user.todos.find(params['id']) @predecessor = current_user.todos.find(params['predecessor']) @successor = @todo @removed = @successor.remove_predecessor(@predecessor) + determine_remaining_in_context_count respond_to do |format| format.js end @@ -239,9 +262,13 @@ class TodosController < ApplicationController # Toggles the 'done' status of the action # def toggle_check + @todo = current_user.todos.find(params['id']) @source_view = params['_source_view'] || 'todo' @original_item_due = @todo.due @original_item_was_deferred = @todo.deferred? + @original_item_was_hidden = @todo.hidden? + @original_item_context_id = @todo.context_id + @original_item_project_id = @todo.project_id @saved = @todo.toggle_completion! # check if this todo has a related recurring_todo. If so, create next todo @@ -265,7 +292,8 @@ class TodosController < ApplicationController determine_remaining_in_context_count(@todo.context_id) determine_down_count determine_completed_count - determine_deferred_tag_count(params['_tag_name']) if @source_view == 'tag' + determine_deferred_tag_count(params['_tag_name']) if source_view_is(:tag) + @wants_redirect_after_complete = @todo.completed? && !@todo.project_id.nil? && current_user.prefs.show_project_on_todo_done && !source_view_is(:project) if source_view_is :calendar @original_item_due_id = get_due_id_for_calendar(@original_item_due) @old_due_empty = is_old_due_empty(@original_item_due_id) @@ -277,10 +305,10 @@ class TodosController < ApplicationController format.html do if @saved # TODO: I think this will work, but can't figure out how to test it - notify :notice, "The action '#{@todo.description}' was marked as #{@todo.completed? ? 'complete' : 'incomplete' }" + notify(:notice, t("todos.action_marked_complete", :description => @todo.description, :completed => @todo.completed? ? 'complete' : 'incomplete')) redirect_to :action => "index" else - notify :notice, "The action '#{@todo.description}' was NOT marked as #{@todo.completed? ? 'complete' : 'incomplete' } due to an error on the server.", "index" + notify(:notice, t("todos.action_marked_complete_error", :description => @todo.description, :completed => @todo.completed? ? 'complete' : 'incomplete'), "index") redirect_to :action => "index" end end @@ -288,15 +316,18 @@ class TodosController < ApplicationController end def toggle_star + @todo = current_user.todos.find(params['id'], :include => [:taggings, :tags]) @todo.toggle_star! - @saved = @todo.save! + @saved = true # cannot determine error respond_to do |format| format.js format.xml { render :xml => @todo.to_xml( :except => :user_id ) } + format.html { redirect_to request.referrer} end end def change_context + # TODO: is this method used? @todo = Todo.find(params[:todo][:id]) @original_item_context_id = @todo.context_id @context = Context.find(params[:todo][:context_id]) @@ -304,7 +335,7 @@ class TodosController < ApplicationController @saved = @todo.save @context_changed = true - @message = "Context changed to #{@context.name}" + @message = t('todos.context_changed', :name => @context.name) determine_remaining_in_context_count(@original_item_context_id) respond_to do |format| @@ -314,124 +345,41 @@ class TodosController < ApplicationController end def update + @todo = current_user.todos.find(params['id']) @source_view = params['_source_view'] || 'todo' init_data_for_sidebar unless mobile? - if params[:tag_list] - @todo.tag_with(params[:tag_list]) - @todo.tags(true) #force a reload for proper rendering - end - @original_item_context_id = @todo.context_id - @original_item_project_id = @todo.project_id - @original_item_was_deferred = @todo.deferred? - @original_item_due = @todo.due - @original_item_due_id = get_due_id_for_calendar(@todo.due) - @original_item_predecessor_list = @todo.predecessors.map{|t| t.specification}.join(', ') - - if params['todo']['project_id'].blank? && !params['project_name'].nil? - if params['project_name'] == 'None' - project = Project.null_object - else - project = current_user.projects.find_by_name(params['project_name'].strip) - unless project - project = current_user.projects.build - project.name = params['project_name'].strip - project.save - @new_project_created = true - end - end - params["todo"]["project_id"] = project.id - end - - if params['todo']['context_id'].blank? && !params['context_name'].blank? - context = current_user.contexts.find_by_name(params['context_name'].strip) - unless context - context = current_user.contexts.build - context.name = params['context_name'].strip - context.save - @new_context_created = true - @not_done_todos = [@todo] - end - params["todo"]["context_id"] = context.id - end - - if params["todo"].has_key?("due") - params["todo"]["due"] = parse_date_per_user_prefs(params["todo"]["due"]) - else - params["todo"]["due"] = "" - end - - if params['todo']['show_from'] - params['todo']['show_from'] = parse_date_per_user_prefs(params['todo']['show_from']) - end - - if params['done'] == '1' && !@todo.completed? - @todo.complete! - @todo.pending_to_activate.each do |t| - t.activate! - end - end - # strange. if checkbox is not checked, there is no 'done' in params. - # Therefore I've used the negation - if !(params['done'] == '1') && @todo.completed? - @todo.activate! - @todo.active_to_block.each do |t| - t.block! - end - end - - @todo.attributes = params["todo"] - @todo.add_predecessor_list(params[:predecessor_list]) + cache_attributes_from_before_update + + update_tags + update_project + update_context + update_due_and_show_from_dates + update_completed_state + update_dependencies + update_attributes_of_todo + @saved = @todo.save - if @saved && params[:predecessor_list] - if @original_item_predecessor_list != params[:predecessor_list] - # Possible state change with new dependencies - if @todo.uncompleted_predecessors.empty? - if @todo.state == 'pending' - @todo.activate! # Activate pending if no uncompleted predecessors - end - else - if @todo.state == 'active' - @todo.block! # Block active if we got uncompleted predecessors - end - end - end - @todo.save! - end - @context_changed = @original_item_context_id != @todo.context_id - @todo_was_activated_from_deferred_state = @original_item_was_deferred && @todo.active? + # this is set after save and cleared after reload, so save it here + @removed_predecessors = @todo.removed_predecessors - if source_view_is :calendar - @due_date_changed = @original_item_due != @todo.due - if @due_date_changed - @old_due_empty = is_old_due_empty(@original_item_due_id) - if @todo.due.nil? - # do not act further on date change when date is changed to nil - @due_date_changed = false - else - @new_due_id = get_due_id_for_calendar(@todo.due) - end - end - end - - if @context_changed - determine_remaining_in_context_count(@original_item_context_id) - else - determine_remaining_in_context_count(@todo.context_id) - end - - @project_changed = @original_item_project_id != @todo.project_id - if (@project_changed && !@original_item_project_id.nil?) then - @todo.update_state_from_project - @todo.save! - @remaining_undone_in_project = current_user.projects.find(@original_item_project_id).not_done_todos.count - end + @todo.reload # refresh context and project object too (not only their id's) + + update_dependency_state + update_todo_state_if_project_changed + + determine_changes_by_this_update + determine_remaining_in_context_count(@context_changed ? @original_item_context_id : @todo.context_id) determine_down_count - determine_deferred_tag_count(params['_tag_name']) if @source_view == 'tag' + determine_deferred_tag_count(params['_tag_name']) if source_view_is(:tag) respond_to do |format| - format.js + format.js { + @status_message = @todo.deferred? ? t('todos.action_saved_to_tickler') : t('todos.action_saved') + @status_message = t('todos.added_new_project') + ' / ' + @status_message if @new_project_created + @status_message = t('todos.added_new_context') + ' / ' + @status_message if @new_context_created + } format.xml { render :xml => @todo.to_xml( :except => :user_id ) } format.m do if @saved @@ -450,7 +398,8 @@ class TodosController < ApplicationController end def destroy - @todo = get_todo_from_params + @source_view = params['_source_view'] || 'todo' + @todo = current_user.todos.find(params['id'], :include => [:pending_successors, :uncompleted_predecessors, :taggings, :tags, :project, :context]) @original_item_due = @todo.due @context_id = @todo.context_id @project_id = @todo.project_id @@ -476,14 +425,14 @@ class TodosController < ApplicationController format.html do if @saved - message = "Successfully deleted next action" + message = t('todos.action_deleted_success') if activated_successor_count > 0 message += " activated #{pluralize(activated_successor_count, 'pending action')}" end notify :notice, message, 2.0 redirect_to :action => 'index' else - notify :error, "Failed to delete the action", 2.0 + notify :error, t('todos.action_deleted_error'), 2.0 redirect_to :action => 'index' end end @@ -507,7 +456,7 @@ class TodosController < ApplicationController end def completed - @page_title = "TRACKS::Completed tasks" + @page_title = t('todos.completed_tasks_title') @done = current_user.completed_todos @done_today = @done.completed_within Time.zone.now - 1.day @done_this_week = @done.completed_within Time.zone.now - 1.week @@ -516,7 +465,7 @@ class TodosController < ApplicationController end def completed_archive - @page_title = "TRACKS::Archived completed tasks" + @page_title = t('todos.archived_tasks_title') @done = current_user.completed_todos @count = @done.size @done_archive = @done.completed_more_than Time.zone.now - 28.days @@ -524,7 +473,7 @@ class TodosController < ApplicationController def list_deferred @source_view = 'deferred' - @page_title = "TRACKS::Tickler" + @page_title = t('todos.deferred_tasks_title') @contexts_to_show = @contexts = current_user.contexts.find(:all) @@ -559,37 +508,32 @@ class TodosController < ApplicationController # /todos/tag/[tag_name] shows all the actions tagged with tag_name def tag + init_data_for_sidebar unless mobile? @source_view = params['_source_view'] || 'tag' @tag_name = params[:name] - @page_title = "TRACKS::Tagged with \'#{@tag_name}\'" + @page_title = t('todos.tagged_page_title', :tag_name => @tag_name) # mobile tags are routed with :name ending on .m. So we need to chomp it @tag_name = @tag_name.chomp('.m') if mobile? @tag = Tag.find_by_name(@tag_name) @tag = Tag.new(:name => @tag_name) if @tag.nil? - tag_collection = @tag.todos - @not_done_todos = tag_collection.find(:all, - :conditions => ['todos.user_id = ? and state = ?', current_user.id, 'active'], - :order => 'todos.due IS NULL, todos.due ASC, todos.created_at ASC') - @hidden_todos = current_user.todos.find(:all, + @not_done_todos = current_user.todos.with_tag(@tag).active.not_hidden.find(:all, + :order => 'todos.due IS NULL, todos.due ASC, todos.created_at ASC', :include => [:context]) + @hidden_todos = current_user.todos.with_tag(@tag).hidden.find(:all, :include => [:taggings, :tags, :context], - :conditions => ['tags.name = ? AND (todos.state = ? OR (contexts.hide = ? AND todos.state = ?))', @tag_name, 'project_hidden', true, 'active'], :order => 'todos.completed_at DESC, todos.created_at DESC') - @deferred = tag_collection.find(:all, - :conditions => ['todos.user_id = ? and state = ?', current_user.id, 'deferred'], - :order => 'show_from ASC, todos.created_at DESC') - @pending = tag_collection.find(:all, - :conditions => ['todos.user_id = ? and state = ?', current_user.id, 'pending'], - :order => 'show_from ASC, todos.created_at DESC') + @deferred = current_user.todos.with_tag(@tag).deferred.find(:all, + :order => 'show_from ASC, todos.created_at DESC', :include => [:context]) + @pending = current_user.todos.with_tag(@tag).blocked.find(:all, + :order => 'show_from ASC, todos.created_at DESC', :include => [:context]) # If you've set no_completed to zero, the completed items box isn't shown on # the tag page max_completed = current_user.prefs.show_number_completed - @done = tag_collection.find(:all, + @done = current_user.todos.with_tag(@tag).completed.find(:all, :limit => max_completed, - :conditions => ['todos.user_id = ? and state = ?', current_user.id, 'completed'], :order => 'todos.completed_at DESC') @projects = current_user.projects @@ -616,25 +560,38 @@ class TodosController < ApplicationController end def tags - @tags = Tag.all + @tags = Tag.find(:all, :conditions =>['name like ?', '%'+params[:term]+'%']) respond_to do |format| - format.autocomplete { render :text => for_autocomplete(@tags, params[:q]) } + format.autocomplete { render :text => for_autocomplete(@tags, params[:term]) } end end def defer @source_view = params['_source_view'] || 'todo' numdays = params['days'].to_i - @todo = Todo.find(params[:id]) + + @todo = current_user.todos.find(params[:id], :include => [:taggings, :tags, :uncompleted_predecessors, :pending_successors]) @original_item_context_id = @todo.context_id + @todo_deferred_state_changed = true + @new_context_created = false + @due_date_changed = false + @tag_was_removed = false + @todo_hidden_state_changed = false + @todo_was_deferred_from_active_state = @todo.show_from.nil? + @todo.show_from = (@todo.show_from || @todo.user.date) + numdays.days @saved = @todo.save determine_down_count determine_remaining_in_context_count(@todo.context_id) - if @source_view == 'project' - @remaining_undone_in_project = current_user.projects.find(@todo.project_id).not_done_todos.count - @original_item_project_id = @todo.project_id + source_view do |page| + page.project { + @remaining_undone_in_project = current_user.projects.find(@todo.project_id).todos.not_completed.count + @original_item_project_id = @todo.project_id + } + page.tag { + determine_deferred_tag_count(params['_tag_name']) + } end respond_to do |format| @@ -645,7 +602,7 @@ class TodosController < ApplicationController def calendar @source_view = params['_source_view'] || 'calendar' - @page_title = "TRACKS::Calendar" + @page_title = t('todos.calendar_page_title') @projects = current_user.projects.find(:all) @@ -707,7 +664,7 @@ class TodosController < ApplicationController :conditions => [ '(todos.state = ? OR todos.state = ? OR todos.state = ?) AND ' + 'NOT (id = ?) AND lower(description) LIKE ?', 'active', 'pending', 'deferred', - params[:id], '%' + params[:q].downcase + '%' ], + params[:id], '%' + params[:term].downcase + '%' ], :order => 'description ASC', :limit => 10 ) @@ -718,12 +675,12 @@ class TodosController < ApplicationController :select => 'description, project_id, context_id, created_at', :conditions => [ '(todos.state = ? OR todos.state = ? OR todos.state = ?) AND lower(description) LIKE ?', 'active', 'pending', 'deferred', - '%' + params[:q].downcase + '%' ], + '%' + params[:term].downcase + '%' ], :order => 'description ASC', :limit => 10 ) end - render :inline => "<%= auto_complete_result2(@items) %>" + render :inline => auto_complete_result2(@items) end def convert_to_project @@ -736,6 +693,7 @@ class TodosController < ApplicationController end def show_notes + @todo = current_user.todos.find(params['id']) @return_path=cookies[:mobile_url] ? cookies[:mobile_url] : mobile_path respond_to do |format| format.html { @@ -750,6 +708,8 @@ class TodosController < ApplicationController private def get_todo_from_params + # TODO: this was a :append_before but was removed to tune performance per + # method. Reconsider re-enabling it @todo = current_user.todos.find(params['id']) end @@ -778,24 +738,24 @@ class TodosController < ApplicationController condition_builder.add 'todos.state = ?', 'active' end - @title = "Tracks - Next Actions" - @description = "Filter: " + @title = t('todos.next_actions_title') + @description = t('todos.next_actions_description') if params.key?('due') due_within = params['due'].to_i due_within_when = Time.zone.now + due_within.days condition_builder.add('todos.due <= ?', due_within_when) due_within_date_s = due_within_when.strftime("%Y-%m-%d") - @title << " due today" if (due_within == 0) - @title << " due within a week" if (due_within == 6) - @description << " with a due date #{due_within_date_s} or earlier" + @title << t('todos.next_actions_title_additions.due_today') if (due_within == 0) + @title << t('todos.next_actions_title_additions.due_within_a_week') if (due_within == 6) + @description << t('todos.next_actions_description_additions.due_date', :due_date => due_within_date_s) end if params.key?('done') done_in_last = params['done'].to_i condition_builder.add('todos.completed_at >= ?', Time.zone.now - done_in_last.days) - @title << " actions completed" - @description << " in the last #{done_in_last.to_s} days" + @title << t('todos.next_actions_title_additions.completed') + @description << t('todos.next_actions_description_additions.completed', :count => done_in_last.to_s) end if params.key?('tag') @@ -813,16 +773,16 @@ class TodosController < ApplicationController end def with_parent_resource_scope(&block) - @feed_title = "Actions " + @feed_title = t('common.actions') if (params[:context_id]) @context = current_user.contexts.find_by_params(params) - @feed_title = @feed_title + "in context '#{@context.name}'" + @feed_title = @feed_title + t('todos.feed_title_in_context', :context => @context.name) Todo.send :with_scope, :find => {:conditions => ['todos.context_id = ?', @context.id]} do yield end elsif (params[:project_id]) @project = current_user.projects.find_by_params(params) - @feed_title = @feed_title + "in project '#{@project.name}'" + @feed_title = @feed_title + t('todos.feed_title_in_project', :project => @project.name) @project_feed = true Todo.send :with_scope, :find => {:conditions => ['todos.project_id = ?', @project.id]} do yield @@ -839,9 +799,9 @@ class TodosController < ApplicationController end if TodosController.is_feed_request(request) && @description if params.key?('limit') - @description << "Lists the last #{params['limit']} incomplete next actions" + @description << t('todos.list_incomplete_next_actions_with_limit', :count => params['limit']) else - @description << "Lists incomplete next actions" + @description << t('todos.list_incomplete_next_actions') end end else @@ -862,12 +822,11 @@ class TodosController < ApplicationController # current_users.todos.find but that broke with_scope for :limit # Exclude hidden projects from count on home page - @todos = Todo.find(:all, :conditions => ['todos.user_id = ?', current_user.id], :include => [ :project, :context, :tags ]) + @todos = current_user.todos.find(:all, :include => [ :project, :context, :tags ]) # Exclude hidden projects from the home page - @not_done_todos = Todo.find(:all, - :conditions => ['todos.user_id = ? AND contexts.hide = ? AND (projects.state = ? OR todos.project_id IS NULL)', - current_user.id, false, 'active'], + @not_done_todos = current_user.todos.find(:all, + :conditions => ['contexts.hide = ? AND (projects.state = ? OR todos.project_id IS NULL)', false, 'active'], :order => "todos.due IS NULL, todos.due ASC, todos.created_at ASC", :include => [ :project, :context, :tags ]) end @@ -882,9 +841,8 @@ class TodosController < ApplicationController # but that broke with_scope for :limit # Exclude hidden projects from the home page - @not_done_todos = Todo.find(:all, - :conditions => ['todos.user_id = ? AND todos.state = ? AND contexts.hide = ? AND (projects.state = ? OR todos.project_id IS NULL)', - current_user.id, 'active', false, 'active'], + @not_done_todos = current_user.todos.find(:all, + :conditions => ['todos.state = ? AND contexts.hide = ? AND (projects.state = ? OR todos.project_id IS NULL)', 'active', false, 'active'], :order => "todos.due IS NULL, todos.due ASC, todos.created_at ASC", :include => [ :project, :context, :tags ]) end @@ -892,27 +850,18 @@ class TodosController < ApplicationController def determine_down_count source_view do |from| from.todo do - @down_count = Todo.count( - :all, - :conditions => ['todos.user_id = ? and todos.state = ? and contexts.hide = ? AND (projects.state = ? OR todos.project_id IS NULL)', current_user.id, 'active', false, 'active'], - :include => [ :project, :context ]) - # #@down_count = Todo.count_by_sql(['SELECT COUNT(*) FROM todos, - # contexts WHERE todos.context_id = contexts.id and todos.user_id = ? - # and todos.state = ? and contexts.hide = ?', current_user.id, 'active', - # false]) + @down_count = current_user.todos.active.not_hidden.count end from.context do - @down_count = current_user.contexts.find(@todo.context_id).not_done_todo_count + @down_count = current_user.contexts.find(@todo.context_id).todos.not_completed.count(:all) end from.project do unless @todo.project_id == nil - @down_count = current_user.projects.find(@todo.project_id).not_done_todos_including_hidden.count - @deferred_count = current_user.projects.find(@todo.project_id).deferred_todos.count - @pending_count = current_user.projects.find(@todo.project_id).pending_todos.count + @down_count = current_user.projects.find(@todo.project_id).todos.active_or_hidden.count end end from.deferred do - @down_count = current_user.todos.count_in_state(:deferred) + @down_count = current_user.todos.deferred_or_blocked.count(:all) end from.tag do @tag_name = params['_tag_name'] @@ -920,58 +869,72 @@ class TodosController < ApplicationController if @tag.nil? @tag = Tag.new(:name => @tag_name) end - tag_collection = @tag.todos - @not_done_todos = tag_collection.find(:all, :conditions => ['todos.user_id = ? and state = ?', current_user.id, 'active']) - @not_done_todos.empty? ? @down_count = 0 : @down_count = @not_done_todos.size + @down_count = current_user.todos.with_tag(@tag).active.not_hidden.count end end end def determine_remaining_in_context_count(context_id = @todo.context_id) source_view do |from| - from.deferred { @remaining_in_context = current_user.contexts.find(context_id).deferred_todo_count } - from.tag { + from.deferred { + # force reload to todos to get correct count and not a cached one + @remaining_in_context = current_user.contexts.find(context_id).todos.deferred_or_blocked.count + @target_context_count = current_user.contexts.find(@todo.context_id).todos.deferred_or_blocked.count + } + from.tag { tag = Tag.find_by_name(params['_tag_name']) if tag.nil? tag = Tag.new(:name => params['tag']) end - @remaining_in_context = current_user.contexts.find(context_id).not_done_todo_count({:tag => tag.id}) + @remaining_in_context = current_user.contexts.find(context_id).todos.active.not_hidden.with_tag(tag).count + @target_context_count = current_user.contexts.find(@todo.context_id).todos.active.not_hidden.with_tag(tag).count + @remaining_hidden_count = current_user.todos.hidden.with_tag(tag).count + } + from.project { + @remaining_deferred_or_pending_count = current_user.projects.find(@todo.project_id).todos.deferred_or_blocked.count + @remaining_in_context = current_user.projects.find(@todo.project_id).todos.active.count + @target_context_count = current_user.projects.find(@todo.project_id).todos.active.count + } + from.calendar { + @target_context_count = count_old_due_empty(@new_due_id) } end - @remaining_in_context = current_user.contexts.find(context_id).not_done_todo_count if @remaining_in_context.nil? + @remaining_in_context = current_user.contexts.find(context_id).todos(true).active.not_hidden.count if !@remaining_in_context + @target_context_count = current_user.contexts.find(@todo.context_id).todos(true).active.not_hidden.count if !@target_context_count end def determine_completed_count source_view do |from| from.todo do - @completed_count = Todo.count_by_sql(['SELECT COUNT(*) FROM todos, contexts WHERE todos.context_id = contexts.id and todos.user_id = ? and todos.state = ? and contexts.hide = ?', current_user.id, 'completed', false]) + @completed_count = current_user.todos.not_hidden.completed.count end from.context do - @completed_count = current_user.contexts.find(@todo.context_id).done_todo_count + todos = current_user.contexts.find(@todo.context_id).todos.completed + todos = todos.not_hidden if !@todo.context.hidden? + @completed_count = todos.count end from.project do unless @todo.project_id == nil - @completed_count = current_user.projects.find(@todo.project_id).done_todos.count + todos = current_user.projects.find(@todo.project_id).todos.completed + todos = todos.not_hidden if !@todo.project.hidden? + @completed_count = todos.count end end + from.tag do + @completed_count = current_user.todos.with_tag(@tag).completed.count + end end end - def determine_deferred_tag_count(tag) - tags = Tag.find_by_name(tag) - if tags.nil? - # should normally not happen, but is a workaround for #929 - @deferred_tag_count = 0 - else - @deferred_tag_count = tags.todos.count(:all, - :conditions => ['todos.user_id = ? and state = ?', current_user.id, 'deferred'], - :order => 'show_from ASC, todos.created_at DESC') - end + def determine_deferred_tag_count(tag_name) + tag = Tag.find_by_name(tag_name) + # tag.nil? should normally not happen, but is a workaround for #929 + @remaining_deferred_or_pending_count = tag.nil? ? 0 : current_user.todos.deferred.with_tag(tag).count end def render_todos_html lambda do - @page_title = "TRACKS::List tasks" + @page_title = t('todos.task_list_title') # If you've set no_completed to zero, the completed items box isn't shown # on the home page @@ -979,16 +942,7 @@ class TodosController < ApplicationController @done = current_user.completed_todos.find(:all, :limit => max_completed, :include => [ :context, :project, :tags ]) unless max_completed == 0 # Set count badge to number of not-done, not hidden context items - @count = 0 - @todos.each do |x| - if x.active? - if x.project.nil? - @count += 1 if !x.context.hide? - else - @count += 1 if x.project.active? && !x.context.hide? - end - end - end + @count = current_user.todos.active.not_hidden.count(:all) render end @@ -996,7 +950,7 @@ class TodosController < ApplicationController def render_todos_mobile lambda do - @page_title = "All actions" + @page_title = t('todos.mobile_todos_page_title') @home = true cookies[:mobile_url]= { :value => request.request_uri, :secure => SITE_CONFIG['secure_cookies']} determine_down_count @@ -1026,15 +980,15 @@ class TodosController < ApplicationController def todo_feed_content lambda do |i| item_notes = sanitize(markdown( i.notes )) if i.notes? - due = "| + | ||
| + | ||
| + | ||
| - | + |
| + | ||
| + | ||
| - | + |
Hello, <%= @username %>! You are authenticated.
+<%= t('login.cas_logged_in_greeting', :username => @username) %>
<% elsif @username %> -Hello, <%= @username %>! You do not have an account on Tracks. +
<%= t('login.cas_no_user_found', :username => @username) %> <%if SITE_CONFIG['open_signups']%> - If you like to request on please go here to <%= link_to "Request Account" , signup_url %> + <%= t('login.cas_create_account', :signup_link => link_to(t('login.cas_signup_link'), signup_url)) %> <%end%>
<% else %> -<%= link_to("CAS Login", login_cas_url) %>
+<%= link_to(t('login.cas_login'), login_cas_url) %>
<% end %>or, go back to the standard login
<% end %> -<% if show_cas_form %>or, go to the CAS
<% end %> +<% if show_openid_form %><%= t('login.option_separator') %> <%= t('login.login_with_openid') %>
<% end %> +<% if show_database_form %><%= t('login.option_separator') %> <%= t('login.login_standard') %>
<% end %> +<% if show_cas_form %><%= t('login.option_separator') %> <%= t('login.login_cas')%>
<% end %> diff --git a/app/views/projects/index_mobile.rhtml b/app/views/projects/index_mobile.rhtml index a33dce05..0c055b6f 100644 --- a/app/views/projects/index_mobile.rhtml +++ b/app/views/projects/index_mobile.rhtml @@ -1,6 +1,6 @@ -Of all your completed actions, the average time to complete is <%= (@actions_avg_ttc*10).round/10.0 %> days. -The Max-/minimum days to complete is <%= (@actions_max_ttc*10).round/10.0%>/<%= (@actions_min_ttc*10).round/10.0 %>. -The minimum time to complete is <%= @actions_min_ttc_sec %>
+<%= t('stats.actions_avg_completion_time', :count => (@actions_avg_ttc*10).round/10.0) %> +<%= t('stats.actions_min_max_completion_days', :min=> (@actions_max_ttc*10).round/10.0, :max => (@actions_min_ttc*10).round/10.0) %> +<%= t('stats.actions_min_completion_time', :time => @actions_min_ttc_sec) %>
-In the last 30 days you created on average <%=(@sum_actions_created_last30days*10.0/30.0).round/10.0 %> actions -and completed on average <%=(@sum_actions_done_last30days*10.0/30.0).round/10.0%> actions per day. -In the last 12 months you created on average <%=(@sum_actions_created_last12months*10.0/12.0).round/10.0 %> actions -and completed on average <%= (@sum_actions_done_last12months*10.0/12.0).round/10.0%> actions per month.
+<%= t('stats.actions_actions_avg_created_30days', :count => (@sum_actions_created_last30days*10.0/30.0).round/10.0 )%> +<%= t('stats.actions_avg_completed_30days', :count => (@sum_actions_done_last30days*10.0/30.0).round/10.0 )%> +<%= t('stats.actions_avg_created', :count => (@sum_actions_created_last12months*10.0/12.0).round/10.0 )%> +<%= t('stats.actions_avg_completed', :count => (@sum_actions_done_last12months*10.0/12.0).round/10.0 )%>
<% %w{ actions_done_last30days_data actions_done_last12months_data diff --git a/app/views/stats/_contexts.rhtml b/app/views/stats/_contexts.rhtml index 1c04cb80..ee3eae5e 100755 --- a/app/views/stats/_contexts.rhtml +++ b/app/views/stats/_contexts.rhtml @@ -5,7 +5,7 @@This tag cloud includes tags of all actions (completed, not completed, visible and/or hidden)
+<%= t('stats.tag_cloud_description') %>
<% if @tags_for_cloud.size < 1 - %> no tags available <% + t('stats.no_tags_available') else @tags_for_cloud.each do |t| %> <%= link_to t.name, @@ -18,12 +18,11 @@
This tag cloud includes tags of actions that were created or completed in - the past 90 days.
+<%= t('stats.tag_cloud_90days_description') %>
<% if @tags_for_cloud_90days.size < 1 - %> no tags available <% + t('stats.no_tags_available') else @tags_for_cloud_90days.each do |t| %> <%= link_to t.name, diff --git a/app/views/stats/_totals.rhtml b/app/views/stats/_totals.rhtml index 9cece4b2..33db9cb5 100755 --- a/app/views/stats/_totals.rhtml +++ b/app/views/stats/_totals.rhtml @@ -1,23 +1,23 @@ -
You have <%= @projects.count%> projects. - Of those <%= @projects.active.count%> are active projects, - <%= @projects.hidden.count%> hidden projects and -<%= @projects.completed.count%> completed projects
+<%= t('stats.totals_project_count', :count => @projects.count) %> + <%= t('stats.totals_active_project_count', :count => @projects.active.count) %>, + <%= t('stats.totals_hidden_project_count', :count => @projects.hidden.count) %> + <%= t('stats.totals_completed_project_count', :count => @projects.completed.count) %>
-You have <%= @contexts.count%> contexts. -Of those <%= @contexts.active.count%> are visible contexts and -<%= @contexts.hidden.count%> are hidden contexts +
<%= t('stats.totals_context_count', :count => @contexts.count ) %> +<%= t('stats.totals_visible_context_count', :count => @contexts.active.count) %> +<%= t('stats.totals_hidden_context_count', :count => @contexts.hidden.count) %> <% unless @actions.empty? -%> -
Since your first action on <%= format_date(@first_action.created_at) %> -you have a total of <%= @actions.count %> actions. -<%= @actions.completed.count %> of these are completed. +
<%= t('stats.totals_first_action', :date => format_date(@first_action.created_at)) %> +<%= t('stats.totals_action_count', :count => @actions.count) %>, +<%= t('stats.totals_actions_completed', :count => @actions.completed.count) %> -
You have <%= @actions.not_completed.count %> incomplete actions -of which <%= @actions.deferred.count %> are deferred actions -in the tickler and <%= @actions.blocked.count %> are dependent on the completion of other actions. +
<%= t('stats.totals_incomplete_actions', :count => @actions.not_completed.count) %> +<%= t('stats.totals_deferred_actions', :count => @actions.deferred.count) %> +<%= t('stats.totals_blocked_actions', :count => @actions.blocked.count) %>
-You have <%= @tags_count-%> tags placed on actions. Of those tags, -<%= @unique_tags_count -%> are unique. +
<%= t('stats.totals_tag_count', :count => @tags_count) %> + <%= t('stats.totals_unique_tags', :count => @unique_tags_count) %> <% end -%> diff --git a/app/views/stats/actions_completion_time_data.html.erb b/app/views/stats/actions_completion_time_data.html.erb index a3b3c44b..be3a8237 100755 --- a/app/views/stats/actions_completion_time_data.html.erb +++ b/app/views/stats/actions_completion_time_data.html.erb @@ -1,7 +1,7 @@ -&title=Completion time (all completed actions),{font-size:16},& -&y_legend=Actions,10,0x8010A0& -&y2_legend=Percentage,10,0xFF0000& -&x_legend=Running time of an action (weeks),12,0x736AFF& +&title=<%= t('stats.action_completion_time_title') %>,{font-size:16},& +&y_legend=<%= t('stats.legend.actions') %>,10,0x8010A0& +&y2_legend=<%= t('stats.legend.percentage') %>,10,0xFF0000& +&x_legend=<%= t('stats.legend.running_time') %>,12,0x736AFF& &y_ticks=5,10,5& &filled_bar=50,0x9933CC,0x8010A0& &values= diff --git a/app/views/stats/actions_day_of_week_30days_data.html.erb b/app/views/stats/actions_day_of_week_30days_data.html.erb index 9505652e..5e884466 100755 --- a/app/views/stats/actions_day_of_week_30days_data.html.erb +++ b/app/views/stats/actions_day_of_week_30days_data.html.erb @@ -1,9 +1,9 @@ -&title=Day of week (past 30 days),{font-size:16},& -&y_legend=Number of actions,12,0x736AFF& -&x_legend=Day of week,12,0x736AFF& +&title=<%= t('stats.actions_dow_30days_title') %>,{font-size:16},& +&y_legend=<%= t('stats.actions_dow_30days_legend.number_of_actions') %>,12,0x736AFF& +&x_legend=<%= t('stats.actions_dow_30days_legend.day_of_week') %>,12,0x736AFF& &y_ticks=5,10,5& -&filled_bar=50,0x9933CC,0x8010A0,Created,8& -&filled_bar_2=50,0x0066CC,0x0066CC,Completed,8& +&filled_bar=50,0x9933CC,0x8010A0,<%= t('stats.labels.created') %>,8& +&filled_bar_2=50,0x0066CC,0x0066CC,<%= t('stats.labels.completed') %>,8& &values=<% 0.upto 5 do |i| -%> <%=@actions_creation_day_array[i] -%>, diff --git a/app/views/stats/actions_day_of_week_all_data.html.erb b/app/views/stats/actions_day_of_week_all_data.html.erb index fee11d73..8accb729 100755 --- a/app/views/stats/actions_day_of_week_all_data.html.erb +++ b/app/views/stats/actions_day_of_week_all_data.html.erb @@ -1,9 +1,9 @@ -&title=Day of week (all actions),{font-size:16},& -&y_legend=Number of actions,12,0x736AFF& -&x_legend=Day of week,12,0x736AFF& +&title=<%= t('stats.actions_day_of_week_title') %>,{font-size:16},& +&y_legend=<%= t('stats.actions_day_of_week_legend.number_of_actions') %>,12,0x736AFF& +&x_legend=<%= t('stats.actions_day_of_week_legend.day_of_week') %>,12,0x736AFF& &y_ticks=5,10,5& -&filled_bar=50,0x9933CC,0x8010A0,Created,8& -&filled_bar_2=50,0x0066CC,0x0066CC,Completed,8& +&filled_bar=50,0x9933CC,0x8010A0,<%= t('stats.labels.created')%>,8& +&filled_bar_2=50,0x0066CC,0x0066CC,<%= t('stats.labels.completed') %>,8& &values=<% 0.upto 5 do |i| -%> <%=@actions_creation_day_array[i] -%>, diff --git a/app/views/stats/actions_done_last12months_data.html.erb b/app/views/stats/actions_done_last12months_data.html.erb index e1191042..4d416e1c 100755 --- a/app/views/stats/actions_done_last12months_data.html.erb +++ b/app/views/stats/actions_done_last12months_data.html.erb @@ -1,13 +1,13 @@ -&title=Actions in the last 12 months,{font-size:16},& -&y_legend=Number of actions,12,0x736AFF& -&x_legend=Months ago,12,0x736AFF& +&title=<%= t('stats.actions_lastyear_title') %>,{font-size:16},& +&y_legend=<%= t('stats.legend.number_of_actions') %>,12,0x736AFF& +&x_legend=<%= t('stats.legend.months_ago') %>,12,0x736AFF& &y_ticks=5,10,5& -&filled_bar=50,0x9933CC,0x8010A0,Created,9& -&filled_bar_2=50,0x0066CC,0x0066CC,Completed,9& -&line_3=2,0x00FF00, Avg Created, 9& -&line_4=2,0xFF0000, Avg Completed, 9& -&line_5=2,0x007700, 3 Month Avg Created, 9& -&line_6=2,0xAA0000, 3 Month Avg Completed, 9& +&filled_bar=50,0x9933CC,0x8010A0,<%= t('stats.labels.created')%>,9& +&filled_bar_2=50,0x0066CC,0x0066CC,<%= t('stats.labels.completed') %>,9& +&line_3=2,0x00FF00, <%= t('stats.labels.avg_created') %>, 9& +&line_4=2,0xFF0000, <%= t('stats.labels.avg_completed') %>, 9& +&line_5=2,0x007700, <%= t('stats.labels.month_avg_created', :months => 3) %>, 9& +&line_6=2,0xAA0000, <%= t('stats.labels.month_avg_completed', :months => 3) %>, 9& &line_7=1,0xAA0000& &line_8=1,0x007700& &values=<% 0.upto 11 do |i| -%><%= @actions_created_last12months_hash[i]%>,<% end -%><%= @actions_created_last12months_hash[12]%>& diff --git a/app/views/stats/actions_done_last30days_data.html.erb b/app/views/stats/actions_done_last30days_data.html.erb index 5eac2776..00efafc8 100755 --- a/app/views/stats/actions_done_last30days_data.html.erb +++ b/app/views/stats/actions_done_last30days_data.html.erb @@ -1,11 +1,11 @@ -&title=Actions in the last 30 days,{font-size:16},& -&y_legend=Number of actions,12,0x736AFF& -&x_legend=Number of days ago,12,0x736AFF& +&title=<%= t('stats.actions_30days_title') %>,{font-size:16},& +&y_legend=<%= t('stats.legend.number_of_actions') %>,12,0x736AFF& +&x_legend=<%= t('stats.legend.number_of_days') %>,12,0x736AFF& &y_ticks=5,10,5& -&filled_bar=50,0x9933CC,0x8010A0,Created,9& -&filled_bar_2=50,0x0066CC,0x0066CC,Completed,9& -&line_3=3,0x00FF00, Avg Created, 9& -&line_4=3,0xFF0000, Avg Completed, 9& +&filled_bar=50,0x9933CC,0x8010A0,<%= t('stats.labels.created') %>,9& +&filled_bar_2=50,0x0066CC,0x0066CC,<%= t('stats.labels.completed') %>,9& +&line_3=3,0x00FF00, <%= t('stats.labels.avg_created') %>, 9& +&line_4=3,0xFF0000, <%= t('stats.labels.avg_completed') %>, 9& &values= <% 0.upto 29 do |i| -%> <%= @actions_created_last30days_hash[i]%>, diff --git a/app/views/stats/actions_done_last_years.html.erb b/app/views/stats/actions_done_last_years.html.erb index 6579d580..0b67a545 100644 --- a/app/views/stats/actions_done_last_years.html.erb +++ b/app/views/stats/actions_done_last_years.html.erb @@ -1,2 +1,2 @@ <%= render :partial => 'chart', :locals => {:width => @chart_width, :height => @chart_height, :data => url_for(:action => :actions_done_lastyears_data)} -%> -Click <%=link_to "here", {:controller => "stats", :action => "index"} %> to return to the statistics page. +<%= t('stats.click_to_return', :link => link_to(t('stats.click_to_return_link'), {:controller => "stats", :action => "index"})) %> diff --git a/app/views/stats/actions_done_lastyears_data.html.erb b/app/views/stats/actions_done_lastyears_data.html.erb index 2619d56a..87245d13 100644 --- a/app/views/stats/actions_done_lastyears_data.html.erb +++ b/app/views/stats/actions_done_lastyears_data.html.erb @@ -1,13 +1,13 @@ -&title=Actions in the last years,{font-size:16},& -&y_legend=Number of actions,12,0x736AFF& -&x_legend=Months ago,12,0x736AFF& +&title=<%= t('stats.actions_last_year') %>,{font-size:16},& +&y_legend=<%= t('stats.actions_last_year_legend.number_of_actions') %>,12,0x736AFF& +&x_legend=<%= t('stats.actions_last_year_legend.months_ago') %>,12,0x736AFF& &y_ticks=5,10,5& &filled_bar=50,0x9933CC,0x8010A0,Created,9& &filled_bar_2=50,0x0066CC,0x0066CC,Completed,9& -&line_3=2,0x00FF00, Avg Created, 9& -&line_4=2,0xFF0000, Avg Completed, 9& -&line_5=2,0x007700, 3 Month Avg Created, 9& -&line_6=2,0xAA0000, 3 Month Avg Completed, 9& +&line_3=2,0x00FF00, <%= t('stats.labels.avg_created') %>, 9& +&line_4=2,0xFF0000, <%= t('stats.labels.avg_completed') %>, 9& +&line_5=2,0x007700, <%= t('stats.labels.month_avg_created', :months => 3) %>, 9& +&line_6=2,0xAA0000, <%= t('stats.labels.month_avg_completed', :months => 3) %>, 9& &line_7=1,0xAA0000& &line_8=1,0x007700& &values=<% 0.upto @month_count-1 do |i| -%><%= @actions_created_last_months_hash[i]%>,<% end -%><%= @actions_created_last_months_hash[@month_count]%>& diff --git a/app/views/stats/actions_running_time_data.html.erb b/app/views/stats/actions_running_time_data.html.erb index 70865846..a8a56300 100755 --- a/app/views/stats/actions_running_time_data.html.erb +++ b/app/views/stats/actions_running_time_data.html.erb @@ -1,7 +1,7 @@ -&title=Current running time of all incomplete actions,{font-size:16},& -&y_legend=Actions,10,0x736AFF& -&y2_legend=Percentage,10,0xFF0000& -&x_legend=Running time of an action (weeks). Click on a bar for more info,11,0x736AFF& +&title=<%= t('stats.running_time_all') %>,{font-size:16},& +&y_legend=<%= t('stats.running_time_all_legend.actions') %>",10,0x736AFF& +&y2_legend=<%= t('stats.running_time_all_legend.percentage') %>,10,0xFF0000& +&x_legend=<%= t('stats.running_time_all_legend.running_time') %>,11,0x736AFF& &y_ticks=5,10,5& &filled_bar=50,0x9933CC,0x8010A0& &values= diff --git a/app/views/stats/actions_time_of_day_30days_data.html.erb b/app/views/stats/actions_time_of_day_30days_data.html.erb index 12a459c2..6f48b43a 100755 --- a/app/views/stats/actions_time_of_day_30days_data.html.erb +++ b/app/views/stats/actions_time_of_day_30days_data.html.erb @@ -1,9 +1,9 @@ -&title=Time of day (last 30 days),{font-size:16},& -&y_legend=Number of actions,12,0x736AFF& -&x_legend=Time of Day,12,0x736AFF& +&title=<%= t('stats.tod30') %>,{font-size:16},& +&y_legend=<%= t('stats.tod30_legend.number_of_actions') %>,12,0x736AFF& +&x_legend=<%= t('stats.tod30_legend.time_of_day') %>,12,0x736AFF& &y_ticks=5,10,5& -&filled_bar=50,0x9933CC,0x8010A0,Created,8& -&filled_bar_2=50,0x0066CC,0x0066CC,Completed,8& +&filled_bar=50,0x9933CC,0x8010A0,<%= t('stats.labels.created') %>,8& +&filled_bar_2=50,0x0066CC,0x0066CC,<%= t('stats.labels.completed') %>,8& &values=<% 0.upto 22 do |i| -%> <%=@actions_creation_hour_array[i] -%>, diff --git a/app/views/stats/actions_time_of_day_all_data.html.erb b/app/views/stats/actions_time_of_day_all_data.html.erb index c1b4ff3b..367c4078 100755 --- a/app/views/stats/actions_time_of_day_all_data.html.erb +++ b/app/views/stats/actions_time_of_day_all_data.html.erb @@ -1,9 +1,9 @@ -&title=Time of day (all actions),{font-size:16},& -&y_legend=Number of actions,12,0x736AFF& -&x_legend=Time of Day,12,0x736AFF& +&title=<%= t('stats.time_of_day') %>,{font-size:16},& +&y_legend=<%= t('stats.time_of_day_legend.number_of_actions') %>,12,0x736AFF& +&x_legend=<%= t('stats.time_of_day_legend.time_of_day') %>,12,0x736AFF& &y_ticks=5,10,5& -&filled_bar=50,0x9933CC,0x8010A0,Created,8& -&filled_bar_2=50,0x0066CC,0x0066CC,Completed,8& +&filled_bar=50,0x9933CC,0x8010A0,<%= t('stats.labels.created') %>,8& +&filled_bar_2=50,0x0066CC,0x0066CC,<%= t('stats.labels.completed') %>,8& &values=<% 0.upto 22 do |i| -%> <%=@actions_creation_hour_array[i] -%>, diff --git a/app/views/stats/actions_visible_running_time_data.html.erb b/app/views/stats/actions_visible_running_time_data.html.erb index 09d7035d..c4c70505 100755 --- a/app/views/stats/actions_visible_running_time_data.html.erb +++ b/app/views/stats/actions_visible_running_time_data.html.erb @@ -1,7 +1,7 @@ -&title=Current running time of incomplete visible actions,{font-size:16},& -&y_legend=Actions,10,0x736AFF& -&y2_legend=Percentage,10,0xFF0000& -&x_legend=Running time of an action (weeks). Click on a bar for more info,11,0x736AFF& +&title=<%= t('stats.current_running_time_of_incomplete_visible_actions') %>,{font-size:16},& +&y_legend=<%= t('stats.running_time_legend.actions') %>,10,0x736AFF& +&y2_legend=<%= t('stats.running_time_legend.percentage') %>,10,0xFF0000& +&x_legend=<%= t('stats.running_time_legend.weeks') %>,11,0x736AFF& &y_ticks=5,10,5& &filled_bar=50,0x9933CC,0x8010A0& &values= diff --git a/app/views/stats/context_running_actions_data.html.erb b/app/views/stats/context_running_actions_data.html.erb index 4ee6b264..c856b71c 100755 --- a/app/views/stats/context_running_actions_data.html.erb +++ b/app/views/stats/context_running_actions_data.html.erb @@ -1,4 +1,4 @@ -&title=Spread of running actions for visible contexts,{font-size:16}& +&title=<%= t('stats.spread_of_running_actions_for_visible_contexts') %>,{font-size:16}& &pie=60,#505050,{font-size: 12px; color: #404040;}& &x_axis_steps=1& &y_ticks=5,10,5& &line=3,#87421F& &y_min=0& &y_max=20& &values=<% diff --git a/app/views/stats/context_total_actions_data.html.erb b/app/views/stats/context_total_actions_data.html.erb index 7c32e491..4f9c7679 100755 --- a/app/views/stats/context_total_actions_data.html.erb +++ b/app/views/stats/context_total_actions_data.html.erb @@ -1,4 +1,4 @@ -&title=Spread of actions for all context,{font-size:16}& +&title=<%= t('stats.spread_of_actions_for_all_context') %>,{font-size:16}& &pie=70,#505050,{font-size: 12px; color: #404040;}& &x_axis_steps=1& &y_ticks=5,10,5& &line=3,#87421F& &y_min=0& &y_max=20& &values=<% diff --git a/app/views/stats/index.html.erb b/app/views/stats/index.html.erb index 7e3e9aa8..46073cd9 100755 --- a/app/views/stats/index.html.erb +++ b/app/views/stats/index.html.erb @@ -1,29 +1,29 @@
More statistics will appear here once you have added some actions.
+<%= t('stats.more_stats_will_appear') %>
<% end -%> diff --git a/app/views/stats/show_selection_from_chart.html.erb b/app/views/stats/show_selection_from_chart.html.erb index 3da85a4c..28c13b18 100644 --- a/app/views/stats/show_selection_from_chart.html.erb +++ b/app/views/stats/show_selection_from_chart.html.erb @@ -1,17 +1,15 @@ <%= render :partial => 'chart', :locals => {:width => @chart_width, :height => @chart_height, :data => url_for(:action => @chart_name)} -%>Click on a bar in the chart to update the actions below. Click <%=link_to "here", {:controller => "stats", :action => "index"} %> to return to the statistics page. <% - unless @further -%> <%= - "Click " + - link_to("here", {:controller => "stats", :action => "show_selected_actions_from_chart", :id=>"#{params[:id]}_end", :index => params[:index]})+ - " to show the actions from week " + params[:index] + " and further." -%> +
<%= t('stats.click_to_update_actions') %> <%= t('stats.click_to_return', :link => link_to(t('stats.click_to_return_link'), {:controller => "stats", :action => "index"})) %> <% + unless @further -%> <%= + t('stats.click_to_show_actions_from_week', :link => link_to("here", {:controller => "stats", :action => "show_selected_actions_from_chart", :id=>"#{params[:id]}_end", :index => params[:index]}), :week => params[:index]) -%> <% end %>
<%= check_box_tag("done", 1, @todo && @todo.completed?, "tabindex" => 1) %>
+<%= check_box_tag("done", 1, @todo && @todo.completed?, "tabindex" => 1) %>
<% end -%> - + <%= text_field( "todo", "description", "tabindex" => 2, "maxlength" => 100, "size" => 50) %> - + <%= text_area( "todo", "notes", "cols" => 40, "rows" => 3, "tabindex" => 3) %> - + <%= unless @mobile_from_context collection_select( "todo", "context_id", @contexts, "id", "name", {}, {"tabindex" => 4} ) else @@ -19,10 +19,10 @@ else @contexts, "id", "name", @mobile_from_context.id), {"id" => :todo_context_id, :tabindex => 4} ) end %> - + <%= unless @mobile_from_project collection_select( "todo", "project_id", @projects, "id", "name", - {:include_blank => '--No project--'}, {"tabindex" => 5} ) + {:include_blank => t('todos.no_project')}, {"tabindex" => 5} ) else # manually add blank option since :include_blank does not work # with options_from_collection_for_select @@ -30,11 +30,11 @@ else @projects, "id", "name", @mobile_from_project.id), {"id" => :todo_project_id, :tabindex => 5} ) end %> - + <%= text_field_tag "tag_list", @tag_list_text, :size => 50, :tabindex => 6 %> - + <%= date_select("todo", "due", {:order => [:day, :month, :year], :start_year => this_year, :include_blank => '--'}, :tabindex => 7) %> - + <%= date_select("todo", "show_from", {:order => [:day, :month, :year], :start_year => this_year, :include_blank => true}, :tabindex => 8) %> diff --git a/app/views/todos/_hidden.rhtml b/app/views/todos/_hidden.rhtml index 21f7b013..cedfb298 100644 --- a/app/views/todos/_hidden.rhtml +++ b/app/views/todos/_hidden.rhtml @@ -3,12 +3,12 @@ <% if collapsible %> <%= image_tag("collapse.png") %> <% end %> - Hidden actions <%= append_descriptor ? append_descriptor : '' %> + <%= t('todos.hidden_actions') %> <%= append_descriptor ? append_descriptor : '' %> diff --git a/app/views/todos/_text_todo.rhtml b/app/views/todos/_text_todo.rhtml index 34939e3f..291bd60c 100644 --- a/app/views/todos/_text_todo.rhtml +++ b/app/views/todos/_text_todo.rhtml @@ -8,11 +8,11 @@ else end if (todo.completed?) && todo.completed_at - result_string << "[Completed: " + format_date(todo.completed_at) + "] " + result_string << "["+ t('todos.completed') +": " + format_date(todo.completed_at) + "] " end if todo.due - result_string << "[Due: " + format_date(todo.due) + "] " + result_string << "[" + t('todos.due') + ": " + format_date(todo.due) + "] " result_string << todo.description + " " else result_string << todo.description + " " diff --git a/app/views/todos/_todo.html.erb b/app/views/todos/_todo.html.erb index dae70ed6..052412df 100644 --- a/app/views/todos/_todo.html.erb +++ b/app/views/todos/_todo.html.erb @@ -1,5 +1,4 @@ <% -@todo = todo suppress_context ||= false suppress_project ||= false suppress_edit_button ||= todo.completed? @@ -9,40 +8,35 @@ parameters += "&_tag_name=#{@tag_name}" if @source_view == 'tag' %><%= link_to('iCal', {:format => 'ics', :token => current_user.token}, :title => "iCal feed" ) %> - - Get this calendar in iCal format
+ - <%= t('todos.calendar.get_in_ical_format') %>You have completed <%= pluralize @done_today.length, 'action' %> so far today.
+<%= t('todos.completed_today', :count => @due_tickles.nil? ? 0 : @due_tickles.length) %>
Older completed items: <%= link_to( "Older than 31 days", done_archive_path ) %>
+<%= t('todos.older_completed_items') %>: <%= link_to( t('todos.older_than_days', :count => 31), done_archive_path ) %>
There <%= @done_archive.length == 1 ? 'is' : 'are' %> <%= pluralize @done_archive.length, 'completed action' %> in the archive.
+<%= t('todos.completed_in_archive', :count => @done_archive.length) %>
Select your new authentication type and click 'Change Authentication Type' to replace your current settings.
+<%= t('users.select_authentication_type') %>
<% form_tag :action => 'update_auth_type' do %> -Enter your new password in the fields below and click 'Change Password' to replace your current password with your new one.
+<%= t('users.change_password_prompt') %>
<% form_tag :action => 'update_password' do %>| + | <%= password_field "updateuser", "password", :size => 40 %> | ||
| + | <%= password_field "updateuser", "password_confirmation", :size => 40 %> | ||
| <%= link_to 'Cancel', preferences_path %> | -<%= submit_tag 'Change password' %> | +<%= link_to t('common.cancel'), preferences_path %> | +<%= submit_tag t('users.change_password_submit') %> |
You have a total of <%= @total_users %> users
+<%= t('users.total_users_count', :count => "#{@total_users}") %>
| Login | -Full name | -Authorization type | -Open ID URL | -Total actions | -Total contexts | -Total projects | -Total notes | +<%= User.human_attribute_name('login') %> | +<%= User.human_attribute_name('display_name') %> | +<%= User.human_attribute_name('auth_type') %> | +<%= User.human_attribute_name('open_id_url') %> | +<%= t('users.total_actions') %> | +<%= t('users.total_contexts') %> | +<%= t('users.total_projects') %> | +<%= t('users.total_notes') %> | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| <%=h user.login %> | -<%=h user.last_name? ? user.display_name : '-' %> | +<%=h user.display_name %> | <%= h user.auth_type %> | <%= h user.open_id_url || '-' %> | <%= h user.todos.size %> | <%= h user.contexts.size %> | <%= h user.projects.size %> | <%= h user.notes.size %> | -<%= !user.is_admin? ? link_to_remote( - image_tag("blank.png", :title =>"Destroy user", :class=>"delete_item"), - { :url => user_path(user.id), :method => :delete, - :confirm => "Warning: this will delete user \'#{user.login}\', all their actions, contexts, project and notes. Are you sure that you want to continue?" }, - { :class => "icon" } ) : " " %> | +<%= !user.is_admin? ? remote_delete_user(user) : " " %> |
<%= link_to 'Signup new user', signup_path %>
\ No newline at end of file +<%= link_to t('users.signup_new_user'), signup_path %>
\ No newline at end of file diff --git a/app/views/users/new.html.erb b/app/views/users/new.html.erb index 08bfa3f4..a89ee5d0 100644 --- a/app/views/users/new.html.erb +++ b/app/views/users/new.html.erb @@ -1,4 +1,4 @@ -| - | "<%= session[:cas_user]%>" | -- <%= hidden_field "user", "login", :value => session[:cas_user] %> - <%= hidden_field "user", "password", :value => session[:cas_user] %> - <%= hidden_field "user", "password_confirmation", :value => session[:cas_user] %> - <%= hidden_field"user", "auth_type", :value => "cas" %> | -
| + | "<%= session[:cas_user]%>" | ++ <%= hidden_field "user", "login", :value => session[:cas_user] %> + <%= hidden_field "user", "password", :value => session[:cas_user] %> + <%= hidden_field "user", "password_confirmation", :value => session[:cas_user] %> + <%= hidden_field"user", "auth_type", :value => "cas" %> | +
| - | <%= text_field "user", "login", :size => 20 %> | -|
| - | <%= password_field "user", "password", :size => 20 %> | -|
| - | <%= password_field "user", "password_confirmation", :size => 20 %> | -|
| - | <%= select("user", "auth_type", @auth_types, { :include_blank => false })%> | -|
| + | <%= text_field "user", "login", :size => 20 %> | +|
| + | <%= password_field "user", "password", :size => 20 %> | +|
| + | <%= password_field "user", "password_confirmation", :size => 20 %> | +|
| + | <%= text_field "user", "open_id_url", :class => "open_id" %> | +|
| + | <%= select("user", "auth_type", @auth_types, { :include_blank => false })%> | +|
| - | + |
Dieser Server erlaubt keine freie Benutzerregistrierung.
+Bitte wenden Sie sich <%= mail_to "#{@admin_email}", "via E-mail", :encode => "hex" %> an den Administrator, um ein Konto zu erhalten.
+| Ruby | -<%=h frames.first.filename %>: in <%=h frames.first.function %>, line <%=h frames.first.lineno %> |
-
|---|---|
| Web | -<%=h req.request_method %> <%=h(req.host + path)%> |
-
<%=h frame.filename %>: in <%=h frame.function %>
-
- <% if frame.context_line %>
- | Variable | -Value | -
|---|---|
| <%=h key %> | -<%=h val.inspect %> |
-
No GET data.
- <% end %> - -| Variable | -Value | -
|---|---|
| <%=h key %> | -<%=h val.inspect %> |
-
No POST data.
- <% end %> - - -| Variable | -Value | -
|---|---|
| <%=h key %> | -<%=h val.inspect %> |
-
No cookie data.
- <% end %> - -| Variable | -Value | -
|---|---|
| <%=h key %> | -<%=h val %> |
-
- You're seeing this error because you use Rack::ShowExceptions.
-
| Request Method: | -<%=h req.request_method %> | -
|---|---|
| Request URL: | -<%=h req.url %> | -
<%= detail %>
-
- You're seeing this error because you use Rack::ShowStatus.
-
This replaced the div
' - assert_rjs :replace, 'completely_replaced_div', /replaced the div/ - assert_rjs :replace_html, 'replaceable_div', "This goes inside the div" - assert_rjs :show, "post_1", "post_2", "post_3" - assert_rjs :sortable, 'sortable_item' - assert_rjs :toggle, "post_1", "post_2", "post_3" - assert_rjs :visual_effect, :highlight, "posts", :duration => '1.0' - -For the square bracket syntax (page['some_id'].toggle) use :page followed by the id and then subsequent method calls. Assignment requires a '=' at the end of the method name followed by the value. - - assert_rjs :page, 'some_id', :toggle - assert_rjs :page, 'some_id', :style, :color=, 'red' - diff --git a/vendor/plugins/arts/about.yml b/vendor/plugins/arts/about.yml deleted file mode 100644 index 40c59fa6..00000000 --- a/vendor/plugins/arts/about.yml +++ /dev/null @@ -1,7 +0,0 @@ -author: Kevin Clark -summary: RJS Assertion Plugin -homepage: http://glu.ttono.us -plugin: -version: 0.6 -license: MIT -rails_version: 1.1.2+ \ No newline at end of file diff --git a/vendor/plugins/arts/init.rb b/vendor/plugins/arts/init.rb deleted file mode 100644 index f43aa1e2..00000000 --- a/vendor/plugins/arts/init.rb +++ /dev/null @@ -1,3 +0,0 @@ -# Give testing some culture -require 'test/unit/testcase' -Test::Unit::TestCase.send :include, Arts diff --git a/vendor/plugins/arts/install.rb b/vendor/plugins/arts/install.rb deleted file mode 100644 index a63be40f..00000000 --- a/vendor/plugins/arts/install.rb +++ /dev/null @@ -1 +0,0 @@ -puts IO.read(File.join(File.dirname(__FILE__), 'README')) \ No newline at end of file diff --git a/vendor/plugins/arts/lib/arts.rb b/vendor/plugins/arts/lib/arts.rb deleted file mode 100644 index ffc79819..00000000 --- a/vendor/plugins/arts/lib/arts.rb +++ /dev/null @@ -1,141 +0,0 @@ -module Arts - include ActionView::Helpers::PrototypeHelper - include ActionView::Helpers::ScriptaculousHelper - include ActionView::Helpers::JavaScriptHelper - - include ActionView::Helpers::UrlHelper - include ActionView::Helpers::TagHelper - - def assert_rjs(action, *args, &block) - respond_to?("assert_rjs_#{action}") ? - send("assert_rjs_#{action}", *args) : - assert_response_contains(create_generator.send(action, *args, &block), - generic_error(action, args)) - end - - def assert_no_rjs(action, *args, &block) - assert_raises(Test::Unit::AssertionFailedError) { assert_rjs(action, *args, &block) } - end - - def assert_rjs_insert_html(*args) - position = args.shift - item_id = args.shift - - content = extract_matchable_content(args) - - unless content.blank? - case content - when Regexp - assert_match Regexp.new("new Insertion\.#{position.to_s.camelize}(.*#{item_id}.*,.*#{content.source}.*);"), - @response.body - when String - assert_response_contains("new Insertion.#{position.to_s.camelize}(\"#{item_id}\", #{content});", - "No insert_html call found for \n" + - " position: '#{position}' id: '#{item_id}' \ncontent: \n" + - "#{content}\n" + - "in response:\n#{@response.body}") - else - raise "Invalid content type" - end - else - assert_match /Element\.insert\("#{item_id}", \{.*#{position.to_s.downcase}.*\}.*\)\;/, - @response.body - end - end - - def assert_rjs_replace_html(*args) - div = args.shift - content = extract_matchable_content(args) - - unless content.blank? - case content - when Regexp - assert_match Regexp.new("Element.update(.*#{div}.*,.*#{content.source}.*);"), - @response.body - when String - assert_response_contains("Element.update(\"#{div}\", #{content});", - "No replace_html call found on div: '#{div}' and content: \n#{content}\n" + - "in response:\n#{@response.body}") - else - raise "Invalid content type" - end - else - assert_match Regexp.new("Element.update(.*#{div}.*,.*?);"), @response.body - end - end - - def assert_rjs_replace(*args) - div = args.shift - content = extract_matchable_content(args) - - unless content.blank? - case content - when Regexp - assert_match Regexp.new("Element.replace(.*#{div}.*,.*#{content.source}.*);"), - @response.body - when String - assert_response_contains("Element.replace(\"#{div}\", #{content});", - "No replace call found on div: '#{div}' and content: \n#{content}\n" + - "in response:\n#{@response.body}") - else - raise "Invalid content type" - end - else - assert_match Regexp.new("Element.replace(.*#{div}.*,.*?);"), @response.body - end - end - - # To deal with [] syntax. I hate JavaScriptProxy so.. SO very much - def assert_rjs_page(*args) - content = build_method_chain!(args) - assert_match Regexp.new(Regexp.escape(content)), @response.body, - "Content did not include:\n #{content.to_s}" - end - - protected - - def assert_response_contains(str, message) - assert @response.body.to_s.index(str), message - end - - def build_method_chain!(args) - content = create_generator.send(:[], args.shift) # start $('some_id').... - - while !args.empty? - if (method = args.shift.to_s) =~ /(.*)=$/ - content = content.__send__(method, args.shift) - break - else - content = content.__send__(method) - content = content.__send__(:function_chain).first if args.empty? - end - end - - content - end - - def create_generator - block = Proc.new { |*args| yield *args if block_given? } - JavaScriptGenerator.new self, &block - end - - def generic_error(action, args) - "#{action} with args [#{args.join(" ")}] does not show up in response:\n#{@response.body}" - end - - def extract_matchable_content(args) - if args.size == 1 and args.first.is_a? Regexp - return args.first - else - return create_generator.send(:arguments_for_call, args) - end - end - - public - - # hack for rails 2.2.2 - def with_output_buffer(lines=[], &block) - block.call - end - -end \ No newline at end of file diff --git a/vendor/plugins/arts/test/arts_test.rb b/vendor/plugins/arts/test/arts_test.rb deleted file mode 100644 index fad2be37..00000000 --- a/vendor/plugins/arts/test/arts_test.rb +++ /dev/null @@ -1,402 +0,0 @@ -$:.unshift(File.dirname(__FILE__) + '/../lib') - -require File.dirname(__FILE__) + '/../../../../config/environment' -require 'test/unit' -require 'rubygems' -require 'breakpoint' - -require 'action_controller/test_process' - -ActionController::Base.logger = nil -ActionController::Base.ignore_missing_templates = false -ActionController::Routing::Routes.reload rescue nil - -class ArtsController < ActionController::Base - def alert - render :update do |page| - page.alert 'This is an alert' - end - end - - def assign - render :update do |page| - page.assign 'a', '2' - end - end - - def call - render :update do |page| - page.call 'foo', 'bar', 'baz' - end - end - - def draggable - render :update do |page| - page.draggable 'my_image', :revert => true - end - end - - def drop_receiving - render :update do |page| - page.drop_receiving "my_cart", :url => { :controller => "cart", :action => "add" } - end - end - - def hide - render :update do |page| - page.hide 'some_div' - end - end - - def insert_html - render :update do |page| - page.insert_html :bottom, 'content', 'Stuff in the content div' - end - end - - def redirect - render :update do |page| - page.redirect_to :controller => 'sample', :action => 'index' - end - end - - def remove - render :update do |page| - page.remove 'offending_div' - end - end - - def replace - render :update do |page| - page.replace 'person_45', '- <%= f.submit "Update" %> -
-<% end %> - -<%= link_to 'Show', @address %> | -<%= link_to 'Back', addresses_path %> diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/addresses/index.html.erb b/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/addresses/index.html.erb deleted file mode 100644 index 86d0d387..00000000 --- a/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/addresses/index.html.erb +++ /dev/null @@ -1,18 +0,0 @@ -| <%= link_to 'Show', address %> | -<%= link_to 'Edit', edit_address_path(address) %> | -<%= link_to 'Destroy', address, :confirm => 'Are you sure?', :method => :delete %> | -
- <%= f.submit "Create" %> -
-<% end %> - -<%= link_to 'Back', addresses_path %> diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/addresses/show.html.erb b/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/addresses/show.html.erb deleted file mode 100644 index a75ddbd5..00000000 --- a/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/addresses/show.html.erb +++ /dev/null @@ -1,3 +0,0 @@ - -<%= link_to 'Edit', edit_address_path(@address) %> | -<%= link_to 'Back', addresses_path %> diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/bones/index.rhtml b/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/bones/index.rhtml deleted file mode 100644 index 06f1dad3..00000000 --- a/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/bones/index.rhtml +++ /dev/null @@ -1,5 +0,0 @@ - -Bones: index
-<% @bones.each do |bone| %> -ID: <%= bone.id %>
-<% end %> diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/layouts/addresses.html.erb b/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/layouts/addresses.html.erb deleted file mode 100644 index 84583552..00000000 --- a/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/layouts/addresses.html.erb +++ /dev/null @@ -1,17 +0,0 @@ - - - - - -<%= flash[:notice] %>
- -<%= yield %> - - - diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/layouts/sellers.html.erb b/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/layouts/sellers.html.erb deleted file mode 100644 index bc08e9be..00000000 --- a/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/layouts/sellers.html.erb +++ /dev/null @@ -1,17 +0,0 @@ - - - - - -<%= flash[:notice] %>
- -<%= yield %> - - - diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/layouts/states.html.erb b/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/layouts/states.html.erb deleted file mode 100644 index b2b086fd..00000000 --- a/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/layouts/states.html.erb +++ /dev/null @@ -1,17 +0,0 @@ - - - - - -<%= flash[:notice] %>
- -<%= yield %> - - - diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/layouts/users.html.erb b/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/layouts/users.html.erb deleted file mode 100644 index 23757aa6..00000000 --- a/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/layouts/users.html.erb +++ /dev/null @@ -1,17 +0,0 @@ - - - - - -<%= flash[:notice] %>
- -<%= yield %> - - - diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/sellers/edit.html.erb b/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/sellers/edit.html.erb deleted file mode 100644 index 14c41036..00000000 --- a/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/sellers/edit.html.erb +++ /dev/null @@ -1,12 +0,0 @@ -- <%= f.submit "Update" %> -
-<% end %> - -<%= link_to 'Show', @seller %> | -<%= link_to 'Back', sellers_path %> diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/sellers/index.html.erb b/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/sellers/index.html.erb deleted file mode 100644 index 97ef0457..00000000 --- a/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/sellers/index.html.erb +++ /dev/null @@ -1,20 +0,0 @@ -| <%= h(seller.company_name) %> | -<%= h(display_address(seller)) %> | -<%= link_to 'Show', seller %> | -<%= link_to 'Edit', edit_seller_path(seller) %> | -<%= link_to 'Destroy', seller, :confirm => 'Are you sure?', :method => :delete %> | -
- <%= f.submit "Create" %> -
-<% end %> - -<%= link_to 'Back', sellers_path %> diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/sellers/show.html.erb b/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/sellers/show.html.erb deleted file mode 100644 index f21dcfa7..00000000 --- a/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/sellers/show.html.erb +++ /dev/null @@ -1,3 +0,0 @@ - -<%= link_to 'Edit', edit_seller_path(@seller) %> | -<%= link_to 'Back', sellers_path %> diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/states/edit.html.erb b/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/states/edit.html.erb deleted file mode 100644 index dc59d08b..00000000 --- a/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/states/edit.html.erb +++ /dev/null @@ -1,12 +0,0 @@ -- <%= f.submit "Update" %> -
-<% end %> - -<%= link_to 'Show', @state %> | -<%= link_to 'Back', states_path %> diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/states/index.html.erb b/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/states/index.html.erb deleted file mode 100644 index 07c11ae1..00000000 --- a/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/states/index.html.erb +++ /dev/null @@ -1,19 +0,0 @@ -| <%= state.name %> | -<%= link_to 'Show', state %> | -<%= link_to 'Edit', edit_state_path(state) %> | -<%= link_to 'Destroy', state, :confirm => 'Are you sure?', :method => :delete %> | -
- <%= f.submit "Create" %> -
-<% end %> - -<%= link_to 'Back', states_path %> diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/states/show.html.erb b/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/states/show.html.erb deleted file mode 100644 index ba5c32fb..00000000 --- a/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/states/show.html.erb +++ /dev/null @@ -1,3 +0,0 @@ - -<%= link_to 'Edit', edit_state_path(@state) %> | -<%= link_to 'Back', states_path %> diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/users/edit.html.erb b/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/users/edit.html.erb deleted file mode 100644 index b497ec93..00000000 --- a/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/users/edit.html.erb +++ /dev/null @@ -1,12 +0,0 @@ -- <%= f.submit "Update" %> -
-<% end %> - -<%= link_to 'Show', @user %> | -<%= link_to 'Back', users_path %> diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/users/index.html.erb b/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/users/index.html.erb deleted file mode 100644 index 6397e64e..00000000 --- a/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/users/index.html.erb +++ /dev/null @@ -1,22 +0,0 @@ -| <%= h(user.login) %> | -<%= h(user.address.line_1) %> | -<%= h(user.address.city) %> | -<%= h(user.address.state.name) %> | -<%= link_to 'Show', user %> | -<%= link_to 'Edit', edit_user_path(user) %> | -<%= link_to 'Destroy', user, :confirm => 'Are you sure?', :method => :delete %> | -
- <%= f.submit "Create" %> -
-<% end %> - -<%= link_to 'Back', users_path %> diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/users/show.html.erb b/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/users/show.html.erb deleted file mode 100644 index 3109a37d..00000000 --- a/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/users/show.html.erb +++ /dev/null @@ -1,3 +0,0 @@ - -<%= link_to 'Edit', edit_user_path(@user) %> | -<%= link_to 'Back', users_path %> diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/config/boot.rb b/vendor/plugins/has_many_polymorphs/test/integration/app/config/boot.rb deleted file mode 100644 index cb9a72da..00000000 --- a/vendor/plugins/has_many_polymorphs/test/integration/app/config/boot.rb +++ /dev/null @@ -1,110 +0,0 @@ -# Don't change this file! -# Configure your app in config/environment.rb and config/environments/*.rb - -RAILS_ROOT = "#{File.dirname(__FILE__)}/.." unless defined?(RAILS_ROOT) - -module Rails - class << self - def boot! - unless booted? - preinitialize - pick_boot.run - end - end - - def booted? - defined? Rails::Initializer - end - - def pick_boot - (vendor_rails? ? VendorBoot : GemBoot).new - end - - def vendor_rails? - File.exist?("#{RAILS_ROOT}/vendor/rails") - end - - def preinitialize - load(preinitializer_path) if File.exists?(preinitializer_path) - end - - def preinitializer_path - "#{RAILS_ROOT}/config/preinitializer.rb" - end - end - - class Boot - def run - load_initializer - Rails::Initializer.run(:set_load_path) - end - end - - class VendorBoot < Boot - def load_initializer - require "#{RAILS_ROOT}/vendor/rails/railties/lib/initializer" - end - end - - class GemBoot < Boot - def load_initializer - self.class.load_rubygems - load_rails_gem - require 'initializer' - end - - def load_rails_gem - if version = self.class.gem_version - STDERR.puts "Boot.rb loading version #{version}" - gem 'rails', version - else - STDERR.puts "Boot.rb loading latest available version" - gem 'rails' - end - rescue Gem::LoadError => load_error - $stderr.puts %(Missing the Rails #{version} gem. Please `gem install -v=#{version} rails`, update your RAILS_GEM_VERSION setting in config/environment.rb for the Rails version you do have installed, or comment out RAILS_GEM_VERSION to use the latest version installed.) - exit 1 - end - - class << self - def rubygems_version - Gem::RubyGemsVersion if defined? Gem::RubyGemsVersion - end - - def gem_version - if defined? RAILS_GEM_VERSION - RAILS_GEM_VERSION - elsif ENV.include?('RAILS_GEM_VERSION') - ENV['RAILS_GEM_VERSION'] - else - parse_gem_version(read_environment_rb) - end - end - - def load_rubygems - require 'rubygems' - - unless rubygems_version >= '0.9.4' - $stderr.puts %(Rails requires RubyGems >= 0.9.4 (you have #{rubygems_version}). Please `gem update --system` and try again.) - exit 1 - end - - rescue LoadError - $stderr.puts %(Rails requires RubyGems >= 0.9.4. Please install RubyGems and try again: http://rubygems.rubyforge.org) - exit 1 - end - - def parse_gem_version(text) - $1 if text =~ /^[^#]*RAILS_GEM_VERSION\s*=\s*'([!~<>=]*\s*[\d.]+)'/ - end - - private - def read_environment_rb - File.read("#{RAILS_ROOT}/config/environment.rb") - end - end - end -end - -# All that for this: -Rails.boot! diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/config/database.yml b/vendor/plugins/has_many_polymorphs/test/integration/app/config/database.yml deleted file mode 100644 index c64a5d89..00000000 --- a/vendor/plugins/has_many_polymorphs/test/integration/app/config/database.yml +++ /dev/null @@ -1,17 +0,0 @@ - -defaults: &defaults - adapter: <%= ENV['DB'] || 'mysql' %> - host: localhost - database: hmp_development - username: root - password: - -development: - <<: *defaults - -test: - <<: *defaults - -production: - <<: *defaults - \ No newline at end of file diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/config/environment.rb b/vendor/plugins/has_many_polymorphs/test/integration/app/config/environment.rb deleted file mode 100644 index 39f34dee..00000000 --- a/vendor/plugins/has_many_polymorphs/test/integration/app/config/environment.rb +++ /dev/null @@ -1,19 +0,0 @@ -require File.join(File.dirname(__FILE__), 'boot') -require 'action_controller' - -Rails::Initializer.run do |config| - - if ActionController::Base.respond_to? 'session=' - config.action_controller.session = {:session_key => '_app_session', :secret => '22cde4d5c1a61ba69a81795322cde4d5c1a61ba69a817953'} - end - - config.load_paths << "#{RAILS_ROOT}/app/models/person" # moduleless model path - - config.after_initialize do - config.has_many_polymorphs_options['requirements'] << "#{RAILS_ROOT}/lib/library_model" - end -end - -# Dependencies.log_activity = true - -ENV['RAILS_ASSET_ID'] = Time.now.to_i.to_s diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/config/environment.rb.canonical b/vendor/plugins/has_many_polymorphs/test/integration/app/config/environment.rb.canonical deleted file mode 100644 index 39f34dee..00000000 --- a/vendor/plugins/has_many_polymorphs/test/integration/app/config/environment.rb.canonical +++ /dev/null @@ -1,19 +0,0 @@ -require File.join(File.dirname(__FILE__), 'boot') -require 'action_controller' - -Rails::Initializer.run do |config| - - if ActionController::Base.respond_to? 'session=' - config.action_controller.session = {:session_key => '_app_session', :secret => '22cde4d5c1a61ba69a81795322cde4d5c1a61ba69a817953'} - end - - config.load_paths << "#{RAILS_ROOT}/app/models/person" # moduleless model path - - config.after_initialize do - config.has_many_polymorphs_options['requirements'] << "#{RAILS_ROOT}/lib/library_model" - end -end - -# Dependencies.log_activity = true - -ENV['RAILS_ASSET_ID'] = Time.now.to_i.to_s diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/config/environments/development.rb b/vendor/plugins/has_many_polymorphs/test/integration/app/config/environments/development.rb deleted file mode 100644 index 54ae4ed2..00000000 --- a/vendor/plugins/has_many_polymorphs/test/integration/app/config/environments/development.rb +++ /dev/null @@ -1,9 +0,0 @@ - -config.cache_classes = ENV['PRODUCTION'] -config.whiny_nils = true -config.action_controller.consider_all_requests_local = !ENV['PRODUCTION'] -config.action_controller.perform_caching = ENV['PRODUCTION'] -# The following has been deprecated in Rails 2.1 and removed in 2.2 -config.action_view.cache_template_extensions = ENV['PRODUCTION'] if Rails::VERSION::MAJOR < 2 or Rails::VERSION::MAJOR == 2 && Rails::VERSION::MINOR < 1 -config.action_view.debug_rjs = !ENV['PRODUCTION'] -config.action_mailer.raise_delivery_errors = false diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/config/environments/production.rb b/vendor/plugins/has_many_polymorphs/test/integration/app/config/environments/production.rb deleted file mode 100644 index cb295b83..00000000 --- a/vendor/plugins/has_many_polymorphs/test/integration/app/config/environments/production.rb +++ /dev/null @@ -1,18 +0,0 @@ -# Settings specified here will take precedence over those in config/environment.rb - -# The production environment is meant for finished, "live" apps. -# Code is not reloaded between requests -config.cache_classes = true - -# Use a different logger for distributed setups -# config.logger = SyslogLogger.new - -# Full error reports are disabled and caching is turned on -config.action_controller.consider_all_requests_local = false -config.action_controller.perform_caching = true - -# Enable serving of images, stylesheets, and javascripts from an asset server -# config.action_controller.asset_host = "http://assets.example.com" - -# Disable delivery errors, bad email addresses will be ignored -# config.action_mailer.raise_delivery_errors = false diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/config/environments/test.rb b/vendor/plugins/has_many_polymorphs/test/integration/app/config/environments/test.rb deleted file mode 100644 index f0689b92..00000000 --- a/vendor/plugins/has_many_polymorphs/test/integration/app/config/environments/test.rb +++ /dev/null @@ -1,19 +0,0 @@ -# Settings specified here will take precedence over those in config/environment.rb - -# The test environment is used exclusively to run your application's -# test suite. You never need to work with it otherwise. Remember that -# your test database is "scratch space" for the test suite and is wiped -# and recreated between test runs. Don't rely on the data there! -config.cache_classes = true - -# Log error messages when you accidentally call methods on nil. -config.whiny_nils = true - -# Show full error reports and disable caching -config.action_controller.consider_all_requests_local = true -config.action_controller.perform_caching = false - -# Tell ActionMailer not to deliver emails to the real world. -# The :test delivery method accumulates sent emails in the -# ActionMailer::Base.deliveries array. -config.action_mailer.delivery_method = :test \ No newline at end of file diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/config/locomotive.yml b/vendor/plugins/has_many_polymorphs/test/integration/app/config/locomotive.yml deleted file mode 100644 index 01d79773..00000000 --- a/vendor/plugins/has_many_polymorphs/test/integration/app/config/locomotive.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -mode: development -runs_at_launch: 0 -identifier: testapp -port: 3005 -bundle: /Applications/Locomotive2/Bundles/rmagickRailsMar2007_i386.locobundle \ No newline at end of file diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/config/routes.rb b/vendor/plugins/has_many_polymorphs/test/integration/app/config/routes.rb deleted file mode 100644 index b83b6f4d..00000000 --- a/vendor/plugins/has_many_polymorphs/test/integration/app/config/routes.rb +++ /dev/null @@ -1,33 +0,0 @@ -ActionController::Routing::Routes.draw do |map| - map.resources :states - - map.resources :states - - map.resources :addresses - - map.resources :sellers - - map.resources :users - - # The priority is based upon order of creation: first created -> highest priority. - - # Sample of regular route: - # map.connect 'products/:id', :controller => 'catalog', :action => 'view' - # Keep in mind you can assign values other than :controller and :action - - # Sample of named route: - # map.purchase 'products/:id/purchase', :controller => 'catalog', :action => 'purchase' - # This route can be invoked with purchase_url(:id => product.id) - - # You can have the root of your site routed by hooking up '' - # -- just remember to delete public/index.html. - # map.connect '', :controller => "welcome" - - # Allow downloading Web Service WSDL as a file with an extension - # instead of a file named 'wsdl' - map.connect ':controller/service.wsdl', :action => 'wsdl' - - # Install the default route as the lowest priority. - map.connect ':controller/:action/:id.:format' - map.connect ':controller/:action/:id' -end diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/config/ultrasphinx/default.base b/vendor/plugins/has_many_polymorphs/test/integration/app/config/ultrasphinx/default.base deleted file mode 100644 index 2886ccdc..00000000 --- a/vendor/plugins/has_many_polymorphs/test/integration/app/config/ultrasphinx/default.base +++ /dev/null @@ -1,56 +0,0 @@ -# -# Sphinx/Ultrasphinx user-configurable options. -# -# Copy this file to RAILS_ROOT/config/ultrasphinx. -# You can use individual namespaces if you want (e.g. "development.base"). -# - -indexer -{ - # Indexer running options - mem_limit = 256M -} - -searchd -{ - # Daemon options - # What interface the search daemon should listen on and where to store its logs - address = 0.0.0.0 - port = 3313 - log = /tmp/sphinx/searchd.log - query_log = /tmp/sphinx/query.log - read_timeout = 5 - max_children = 300 - pid_file = /tmp/sphinx/searchd.pid - max_matches = 100000 -} - -client -{ - # Client options - dictionary_name = ts - # How your application connects to the search daemon (not necessarily the same as above) - server_host = localhost - server_port = 3313 -} - -source -{ - # Individual SQL source options - sql_range_step = 20000 - strip_html = 0 - index_html_attrs = - sql_query_post = -} - -index -{ - # Index building options - path = /tmp/sphinx/ - docinfo = extern # just leave this alone - morphology = stem_en - stopwords = # /path/to/stopwords.txt - min_word_len = 1 - charset_type = utf-8 # or sbcs (Single Byte Character Set) - charset_table = 0..9, A..Z->a..z, -, _, ., &, a..z, U+410..U+42F->U+430..U+44F, U+430..U+44F,U+C5->U+E5, U+E5, U+C4->U+E4, U+E4, U+D6->U+F6, U+F6, U+16B, U+0c1->a, U+0c4->a, U+0c9->e, U+0cd->i, U+0d3->o, U+0d4->o, U+0da->u, U+0dd->y, U+0e1->a, U+0e4->a, U+0e9->e, U+0ed->i, U+0f3->o, U+0f4->o, U+0fa->u, U+0fd->y, U+104->U+105, U+105, U+106->U+107, U+10c->c, U+10d->c, U+10e->d, U+10f->d, U+116->U+117, U+117, U+118->U+119, U+11a->e, U+11b->e, U+12E->U+12F, U+12F, U+139->l, U+13a->l, U+13d->l, U+13e->l, U+141->U+142, U+142, U+143->U+144, U+144,U+147->n, U+148->n, U+154->r, U+155->r, U+158->r, U+159->r, U+15A->U+15B, U+15B, U+160->s, U+160->U+161, U+161->s, U+164->t, U+165->t, U+16A->U+16B, U+16B, U+16e->u, U+16f->u, U+172->U+173, U+173, U+179->U+17A, U+17A, U+17B->U+17C, U+17C, U+17d->z, U+17e->z, -} diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/config/ultrasphinx/development.conf.canonical b/vendor/plugins/has_many_polymorphs/test/integration/app/config/ultrasphinx/development.conf.canonical deleted file mode 100644 index f08e8ed4..00000000 --- a/vendor/plugins/has_many_polymorphs/test/integration/app/config/ultrasphinx/development.conf.canonical +++ /dev/null @@ -1,155 +0,0 @@ - -# Auto-generated at Wed Oct 03 03:57:12 -0400 2007. -# Hand modifications will be overwritten. -# /Users/eweaver/Desktop/projects/chow/vendor/plugins/ultrasphinx/test/integration/app/config/ultrasphinx/default.base -indexer { - mem_limit = 256M -} -searchd { - read_timeout = 5 - max_children = 300 - log = /tmp/sphinx/searchd.log - port = 3313 - max_matches = 100000 - query_log = /tmp/sphinx/query.log - pid_file = /tmp/sphinx/searchd.pid - address = 0.0.0.0 -} - -# Source configuration - -source geo__states -{ - strip_html = 0 - sql_range_step = 20000 - index_html_attrs = - sql_query_post = - -type = mysql -sql_query_pre = SET SESSION group_concat_max_len = 65535 -sql_query_pre = SET NAMES utf8 - -sql_db = app_development -sql_host = localhost -sql_pass = -sql_user = root -sql_query_range = SELECT MIN(id), MAX(id) FROM states -sql_query = SELECT (states.id * 4 + 0) AS id, CAST(GROUP_CONCAT(addresses.name SEPARATOR ' ') AS CHAR) AS address_name, 0 AS capitalization, 'Geo::State' AS class, 0 AS class_id, '' AS company, '' AS company_name, 0 AS company_name_facet, '' AS content, UNIX_TIMESTAMP('1970-01-01 00:00:00') AS created_at, 0 AS deleted, '' AS email, '__empty_searchable__' AS empty_searchable, '' AS login, '' AS name, '' AS state, 0 AS user_id FROM states LEFT OUTER JOIN addresses ON states.id = addresses.state_id WHERE states.id >= $start AND states.id <= $end GROUP BY id - -sql_group_column = capitalization -sql_group_column = class_id -sql_group_column = company_name_facet -sql_date_column = created_at -sql_group_column = deleted -sql_group_column = user_id -sql_query_info = SELECT * FROM states WHERE states.id = (($id - 0) / 4) -} - - -# Source configuration - -source sellers -{ - strip_html = 0 - sql_range_step = 20000 - index_html_attrs = - sql_query_post = - -type = mysql -sql_query_pre = SET SESSION group_concat_max_len = 65535 -sql_query_pre = SET NAMES utf8 - -sql_db = app_development -sql_host = localhost -sql_pass = -sql_user = root -sql_query_range = SELECT MIN(id), MAX(id) FROM sellers -sql_query = SELECT (sellers.id * 4 + 1) AS id, '' AS address_name, sellers.capitalization AS capitalization, 'Seller' AS class, 1 AS class_id, '' AS company, sellers.company_name AS company_name, CRC32(sellers.company_name) AS company_name_facet, '' AS content, UNIX_TIMESTAMP(sellers.created_at) AS created_at, 0 AS deleted, '' AS email, '__empty_searchable__' AS empty_searchable, '' AS login, '' AS name, '' AS state, sellers.user_id AS user_id FROM sellers WHERE sellers.id >= $start AND sellers.id <= $end GROUP BY id - -sql_group_column = capitalization -sql_group_column = class_id -sql_group_column = company_name_facet -sql_date_column = created_at -sql_group_column = deleted -sql_group_column = user_id -sql_query_info = SELECT * FROM sellers WHERE sellers.id = (($id - 1) / 4) -} - - -# Source configuration - -source geo__addresses -{ - strip_html = 0 - sql_range_step = 20000 - index_html_attrs = - sql_query_post = - -type = mysql -sql_query_pre = SET SESSION group_concat_max_len = 65535 -sql_query_pre = SET NAMES utf8 - -sql_db = app_development -sql_host = localhost -sql_pass = -sql_user = root -sql_query_range = SELECT MIN(id), MAX(id) FROM addresses -sql_query = SELECT (addresses.id * 4 + 2) AS id, '' AS address_name, 0 AS capitalization, 'Geo::Address' AS class, 2 AS class_id, '' AS company, '' AS company_name, 0 AS company_name_facet, CONCAT_WS(' ', addresses.line_1, addresses.line_2, addresses.city, addresses.province_region, addresses.zip_postal_code) AS content, UNIX_TIMESTAMP('1970-01-01 00:00:00') AS created_at, 0 AS deleted, '' AS email, '__empty_searchable__' AS empty_searchable, '' AS login, addresses.name AS name, states.name AS state, 0 AS user_id FROM addresses LEFT OUTER JOIN states ON states.id = addresses.state_id WHERE addresses.id >= $start AND addresses.id <= $end GROUP BY id - -sql_group_column = capitalization -sql_group_column = class_id -sql_group_column = company_name_facet -sql_date_column = created_at -sql_group_column = deleted -sql_group_column = user_id -sql_query_info = SELECT * FROM addresses WHERE addresses.id = (($id - 2) / 4) -} - - -# Source configuration - -source users -{ - strip_html = 0 - sql_range_step = 20000 - index_html_attrs = - sql_query_post = - -type = mysql -sql_query_pre = SET SESSION group_concat_max_len = 65535 -sql_query_pre = SET NAMES utf8 - -sql_db = app_development -sql_host = localhost -sql_pass = -sql_user = root -sql_query_range = SELECT MIN(id), MAX(id) FROM users -sql_query = SELECT (users.id * 4 + 3) AS id, '' AS address_name, 0 AS capitalization, 'User' AS class, 3 AS class_id, sellers.company_name AS company, '' AS company_name, 0 AS company_name_facet, '' AS content, UNIX_TIMESTAMP('1970-01-01 00:00:00') AS created_at, users.deleted AS deleted, users.email AS email, '__empty_searchable__' AS empty_searchable, users.login AS login, '' AS name, '' AS state, 0 AS user_id FROM users LEFT OUTER JOIN sellers ON users.id = sellers.user_id WHERE users.id >= $start AND users.id <= $end AND (deleted = 0) GROUP BY id - -sql_group_column = capitalization -sql_group_column = class_id -sql_group_column = company_name_facet -sql_date_column = created_at -sql_group_column = deleted -sql_group_column = user_id -sql_query_info = SELECT * FROM users WHERE users.id = (($id - 3) / 4) -} - - -# Index configuration - -index complete -{ - source = geo__addresses - source = geo__states - source = sellers - source = users - charset_type = utf-8 - charset_table = 0..9, A..Z->a..z, -, _, ., &, a..z, U+410..U+42F->U+430..U+44F, U+430..U+44F,U+C5->U+E5, U+E5, U+C4->U+E4, U+E4, U+D6->U+F6, U+F6, U+16B, U+0c1->a, U+0c4->a, U+0c9->e, U+0cd->i, U+0d3->o, U+0d4->o, U+0da->u, U+0dd->y, U+0e1->a, U+0e4->a, U+0e9->e, U+0ed->i, U+0f3->o, U+0f4->o, U+0fa->u, U+0fd->y, U+104->U+105, U+105, U+106->U+107, U+10c->c, U+10d->c, U+10e->d, U+10f->d, U+116->U+117, U+117, U+118->U+119, U+11a->e, U+11b->e, U+12E->U+12F, U+12F, U+139->l, U+13a->l, U+13d->l, U+13e->l, U+141->U+142, U+142, U+143->U+144, U+144,U+147->n, U+148->n, U+154->r, U+155->r, U+158->r, U+159->r, U+15A->U+15B, U+15B, U+160->s, U+160->U+161, U+161->s, U+164->t, U+165->t, U+16A->U+16B, U+16B, U+16e->u, U+16f->u, U+172->U+173, U+173, U+179->U+17A, U+17A, U+17B->U+17C, U+17C, U+17d->z, U+17e->z, - min_word_len = 1 - stopwords = - path = /tmp/sphinx//sphinx_index_complete - docinfo = extern - morphology = stem_en -} - diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/db/migrate/001_create_sticks.rb b/vendor/plugins/has_many_polymorphs/test/integration/app/db/migrate/001_create_sticks.rb deleted file mode 100644 index 6193c313..00000000 --- a/vendor/plugins/has_many_polymorphs/test/integration/app/db/migrate/001_create_sticks.rb +++ /dev/null @@ -1,11 +0,0 @@ -class CreateSticks < ActiveRecord::Migration - def self.up - create_table :sticks do |t| - t.column :name, :string - end - end - - def self.down - drop_table :sticks - end -end diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/db/migrate/002_create_stones.rb b/vendor/plugins/has_many_polymorphs/test/integration/app/db/migrate/002_create_stones.rb deleted file mode 100644 index 4c1ec154..00000000 --- a/vendor/plugins/has_many_polymorphs/test/integration/app/db/migrate/002_create_stones.rb +++ /dev/null @@ -1,11 +0,0 @@ -class CreateStones < ActiveRecord::Migration - def self.up - create_table :stones do |t| - t.column :name, :string - end - end - - def self.down - drop_table :stones - end -end diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/db/migrate/003_create_organic_substances.rb b/vendor/plugins/has_many_polymorphs/test/integration/app/db/migrate/003_create_organic_substances.rb deleted file mode 100644 index 1bf82da6..00000000 --- a/vendor/plugins/has_many_polymorphs/test/integration/app/db/migrate/003_create_organic_substances.rb +++ /dev/null @@ -1,11 +0,0 @@ -class CreateOrganicSubstances < ActiveRecord::Migration - def self.up - create_table :organic_substances do |t| - t.column :type, :string - end - end - - def self.down - drop_table :organic_substances - end -end diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/db/migrate/004_create_bones.rb b/vendor/plugins/has_many_polymorphs/test/integration/app/db/migrate/004_create_bones.rb deleted file mode 100644 index 6faa0aa1..00000000 --- a/vendor/plugins/has_many_polymorphs/test/integration/app/db/migrate/004_create_bones.rb +++ /dev/null @@ -1,8 +0,0 @@ -class CreateBones < ActiveRecord::Migration - def self.up - # Using STI - end - - def self.down - end -end diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/db/migrate/005_create_single_sti_parents.rb b/vendor/plugins/has_many_polymorphs/test/integration/app/db/migrate/005_create_single_sti_parents.rb deleted file mode 100644 index eef14621..00000000 --- a/vendor/plugins/has_many_polymorphs/test/integration/app/db/migrate/005_create_single_sti_parents.rb +++ /dev/null @@ -1,11 +0,0 @@ -class CreateSingleStiParents < ActiveRecord::Migration - def self.up - create_table :single_sti_parents do |t| - t.column :name, :string - end - end - - def self.down - drop_table :single_sti_parents - end -end diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/db/migrate/006_create_double_sti_parents.rb b/vendor/plugins/has_many_polymorphs/test/integration/app/db/migrate/006_create_double_sti_parents.rb deleted file mode 100644 index 2a28f4ab..00000000 --- a/vendor/plugins/has_many_polymorphs/test/integration/app/db/migrate/006_create_double_sti_parents.rb +++ /dev/null @@ -1,11 +0,0 @@ -class CreateDoubleStiParents < ActiveRecord::Migration - def self.up - create_table :double_sti_parents do |t| - t.column :name, :string - end - end - - def self.down - drop_table :double_sti_parents - end -end diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/db/migrate/007_create_single_sti_parent_relationships.rb b/vendor/plugins/has_many_polymorphs/test/integration/app/db/migrate/007_create_single_sti_parent_relationships.rb deleted file mode 100644 index deceeec7..00000000 --- a/vendor/plugins/has_many_polymorphs/test/integration/app/db/migrate/007_create_single_sti_parent_relationships.rb +++ /dev/null @@ -1,13 +0,0 @@ -class CreateSingleStiParentRelationships < ActiveRecord::Migration - def self.up - create_table :single_sti_parent_relationships do |t| - t.column :the_bone_type, :string, :null => false - t.column :the_bone_id, :integer, :null => false - t.column :single_sti_parent_id, :integer, :null => false - end - end - - def self.down - drop_table :single_sti_parent_relationships - end -end diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/db/migrate/008_create_double_sti_parent_relationships.rb b/vendor/plugins/has_many_polymorphs/test/integration/app/db/migrate/008_create_double_sti_parent_relationships.rb deleted file mode 100644 index 46605d9b..00000000 --- a/vendor/plugins/has_many_polymorphs/test/integration/app/db/migrate/008_create_double_sti_parent_relationships.rb +++ /dev/null @@ -1,14 +0,0 @@ -class CreateDoubleStiParentRelationships < ActiveRecord::Migration - def self.up - create_table :double_sti_parent_relationships do |t| - t.column :the_bone_type, :string, :null => false - t.column :the_bone_id, :integer, :null => false - t.column :parent_type, :string, :null => false - t.column :parent_id, :integer, :null => false - end - end - - def self.down - drop_table :double_sti_parent_relationships - end -end diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/db/migrate/009_create_library_model.rb b/vendor/plugins/has_many_polymorphs/test/integration/app/db/migrate/009_create_library_model.rb deleted file mode 100644 index bdf7cf46..00000000 --- a/vendor/plugins/has_many_polymorphs/test/integration/app/db/migrate/009_create_library_model.rb +++ /dev/null @@ -1,11 +0,0 @@ -class CreateLibraryModel < ActiveRecord::Migration - def self.up - create_table :library_models do |t| - t.column :name, :string - end - end - - def self.down - drop_table :library_models - end -end diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/doc/README_FOR_APP b/vendor/plugins/has_many_polymorphs/test/integration/app/doc/README_FOR_APP deleted file mode 100644 index ac6c1491..00000000 --- a/vendor/plugins/has_many_polymorphs/test/integration/app/doc/README_FOR_APP +++ /dev/null @@ -1,2 +0,0 @@ -Use this README file to introduce your application and point to useful places in the API for learning more. -Run "rake appdoc" to generate API documentation for your models and controllers. \ No newline at end of file diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/generators/commenting_generator_test.rb b/vendor/plugins/has_many_polymorphs/test/integration/app/generators/commenting_generator_test.rb deleted file mode 100644 index 0fbdf9a1..00000000 --- a/vendor/plugins/has_many_polymorphs/test/integration/app/generators/commenting_generator_test.rb +++ /dev/null @@ -1,83 +0,0 @@ -require File.dirname(__FILE__) + '/../test_helper' -require 'fileutils' - -class CommentingGeneratorTest < ActiveSupport::TestCase - - def test_ensure_comments_dont_exist - # make sure the comments are already defined - assert_equal false, Object.send(:const_defined?, :Comment) - assert_equal false, Object.send(:const_defined?, :Commenting) - end - - def test_ensure_files_exist_after_generator_runs - run_generator - - # make sure the files are there - for generated_file in generated_files do - assert File.exists?(File.expand_path(generated_file)) - end - end - - def test_classes_exist_with_associations - run_generator - assert_nothing_raised { Commenting } - assert_nothing_raised { Comment } - citation = Citation.find(:first) - assert !citation.nil? - assert citation.respond_to?(:comments) - user = User.find(:first) - assert !user.nil? - assert user.respond_to?(:comments) - end - - def teardown - Object.send(:remove_const, :Comment) if Object.send(:const_defined?, :Comment) - Object.send(:remove_const, :Commenting) if Object.send(:const_defined?, :Commenting) - remove_all_generated_files - remove_require_for_commenting_extensions - end - - def generated_files - generated_files = [File.join(File.dirname(__FILE__), '..', '..', 'app', 'models', 'comment.rb')] - generated_files << File.join(File.dirname(__FILE__), '..', '..', 'app', 'models', 'commenting.rb') - generated_files << File.join(File.dirname(__FILE__), '..', '..', 'test', 'unit', 'commenting_test.rb') - generated_files << File.join(File.dirname(__FILE__), '..', '..', 'test', 'unit', 'comment_test.rb') - generated_files << File.join(File.dirname(__FILE__), '..', '..', 'lib', 'commenting_extensions.rb') - generated_files << File.join(File.dirname(__FILE__), '..', '..', 'test', 'fixtures', 'comments.yml') - generated_files << File.join(File.dirname(__FILE__), '..', '..', 'test', 'fixtures', 'commentings.yml') - end - - def remove_all_generated_files - for generated_file in generated_files do - if File.exists?(generated_file) - assert FileUtils.rm(generated_file) - end - end - end - - def run_migrate - `rake db:migrate RAILS_ENV=test` - end - - def run_generator - command = File.join(File.dirname(__FILE__), '..', '..', 'script', 'generate') - `#{command} commenting Citation User` - run_migrate - end - - def remove_require_for_commenting_extensions - environment = File.join(File.dirname(__FILE__), '..', '..', 'config', 'environment.rb') - new_environment = '' - if File.exists?(environment) - if (open(environment) { |file| file.grep(/Rails/).any? }) - IO.readlines(environment).each do |line| - new_environment += line unless line.match(/commenting_extensions/i) - end - File.open(environment, "w+") do |f| - f.pos = 0 - f.print new_environment - end - end - end - end -end diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/lib/library_model.rb b/vendor/plugins/has_many_polymorphs/test/integration/app/lib/library_model.rb deleted file mode 100644 index e27106fa..00000000 --- a/vendor/plugins/has_many_polymorphs/test/integration/app/lib/library_model.rb +++ /dev/null @@ -1,2 +0,0 @@ -class LibraryModel < ActiveRecord::Base -end diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/public/.htaccess b/vendor/plugins/has_many_polymorphs/test/integration/app/public/.htaccess deleted file mode 100644 index d3c99834..00000000 --- a/vendor/plugins/has_many_polymorphs/test/integration/app/public/.htaccess +++ /dev/null @@ -1,40 +0,0 @@ -# General Apache options -AddHandler fastcgi-script .fcgi -AddHandler cgi-script .cgi -Options +FollowSymLinks +ExecCGI - -# If you don't want Rails to look in certain directories, -# use the following rewrite rules so that Apache won't rewrite certain requests -# -# Example: -# RewriteCond %{REQUEST_URI} ^/notrails.* -# RewriteRule .* - [L] - -# Redirect all requests not available on the filesystem to Rails -# By default the cgi dispatcher is used which is very slow -# -# For better performance replace the dispatcher with the fastcgi one -# -# Example: -# RewriteRule ^(.*)$ dispatch.fcgi [QSA,L] -RewriteEngine On - -# If your Rails application is accessed via an Alias directive, -# then you MUST also set the RewriteBase in this htaccess file. -# -# Example: -# Alias /myrailsapp /path/to/myrailsapp/public -# RewriteBase /myrailsapp - -RewriteRule ^$ index.html [QSA] -RewriteRule ^([^.]+)$ $1.html [QSA] -RewriteCond %{REQUEST_FILENAME} !-f -RewriteRule ^(.*)$ dispatch.cgi [QSA,L] - -# In case Rails experiences terminal errors -# Instead of displaying this message you can supply a file here which will be rendered instead -# -# Example: -# ErrorDocument 500 /500.html - -ErrorDocument 500 "You may have mistyped the address or the page may have moved.
-We've been notified about this issue and we'll take a look at it shortly.
-Rails needs to know your login and password.
-To see all available options, run it without parameters.
-Routes are setup in config/routes.rb.
-/gi, "");
- },
- createEditField: function() {
- var text;
- if(this.options.loadTextURL) {
- text = this.options.loadingText;
- } else {
- text = this.getText();
- }
-
- var obj = this;
-
- if (this.options.rows == 1 && !this.hasHTMLLineBreaks(text)) {
- this.options.textarea = false;
- var textField = document.createElement("input");
- textField.obj = this;
- textField.type = "text";
- textField.name = this.options.paramName;
- textField.value = text;
- textField.style.backgroundColor = this.options.highlightcolor;
- textField.className = 'editor_field';
- var size = this.options.size || this.options.cols || 0;
- if (size != 0) textField.size = size;
- if (this.options.submitOnBlur)
- textField.onblur = this.onSubmit.bind(this);
- this.editField = textField;
- } else {
- this.options.textarea = true;
- var textArea = document.createElement("textarea");
- textArea.obj = this;
- textArea.name = this.options.paramName;
- textArea.value = this.convertHTMLLineBreaks(text);
- textArea.rows = this.options.rows;
- textArea.cols = this.options.cols || 40;
- textArea.className = 'editor_field';
- if (this.options.submitOnBlur)
- textArea.onblur = this.onSubmit.bind(this);
- this.editField = textArea;
- }
-
- if(this.options.loadTextURL) {
- this.loadExternalText();
- }
- this.form.appendChild(this.editField);
- },
- getText: function() {
- return this.element.innerHTML;
- },
- loadExternalText: function() {
- Element.addClassName(this.form, this.options.loadingClassName);
- this.editField.disabled = true;
- new Ajax.Request(
- this.options.loadTextURL,
- Object.extend({
- asynchronous: true,
- onComplete: this.onLoadedExternalText.bind(this)
- }, this.options.ajaxOptions)
- );
- },
- onLoadedExternalText: function(transport) {
- Element.removeClassName(this.form, this.options.loadingClassName);
- this.editField.disabled = false;
- this.editField.value = transport.responseText.stripTags();
- Field.scrollFreeActivate(this.editField);
- },
- onclickCancel: function() {
- this.onComplete();
- this.leaveEditMode();
- return false;
- },
- onFailure: function(transport) {
- this.options.onFailure(transport);
- if (this.oldInnerHTML) {
- this.element.innerHTML = this.oldInnerHTML;
- this.oldInnerHTML = null;
- }
- return false;
- },
- onSubmit: function() {
- // onLoading resets these so we need to save them away for the Ajax call
- var form = this.form;
- var value = this.editField.value;
-
- // do this first, sometimes the ajax call returns before we get a chance to switch on Saving...
- // which means this will actually switch on Saving... *after* we've left edit mode causing Saving...
- // to be displayed indefinitely
- this.onLoading();
-
- if (this.options.evalScripts) {
- new Ajax.Request(
- this.url, Object.extend({
- parameters: this.options.callback(form, value),
- onComplete: this.onComplete.bind(this),
- onFailure: this.onFailure.bind(this),
- asynchronous:true,
- evalScripts:true
- }, this.options.ajaxOptions));
- } else {
- new Ajax.Updater(
- { success: this.element,
- // don't update on failure (this could be an option)
- failure: null },
- this.url, Object.extend({
- parameters: this.options.callback(form, value),
- onComplete: this.onComplete.bind(this),
- onFailure: this.onFailure.bind(this)
- }, this.options.ajaxOptions));
- }
- // stop the event to avoid a page refresh in Safari
- if (arguments.length > 1) {
- Event.stop(arguments[0]);
- }
- return false;
- },
- onLoading: function() {
- this.saving = true;
- this.removeForm();
- this.leaveHover();
- this.showSaving();
- },
- showSaving: function() {
- this.oldInnerHTML = this.element.innerHTML;
- this.element.innerHTML = this.options.savingText;
- Element.addClassName(this.element, this.options.savingClassName);
- this.element.style.backgroundColor = this.originalBackground;
- Element.show(this.element);
- },
- removeForm: function() {
- if(this.form) {
- if (this.form.parentNode) Element.remove(this.form);
- this.form = null;
- }
- },
- enterHover: function() {
- if (this.saving) return;
- this.element.style.backgroundColor = this.options.highlightcolor;
- if (this.effect) {
- this.effect.cancel();
- }
- Element.addClassName(this.element, this.options.hoverClassName)
- },
- leaveHover: function() {
- if (this.options.backgroundColor) {
- this.element.style.backgroundColor = this.oldBackground;
- }
- Element.removeClassName(this.element, this.options.hoverClassName)
- if (this.saving) return;
- this.effect = new Effect.Highlight(this.element, {
- startcolor: this.options.highlightcolor,
- endcolor: this.options.highlightendcolor,
- restorecolor: this.originalBackground
- });
- },
- leaveEditMode: function() {
- Element.removeClassName(this.element, this.options.savingClassName);
- this.removeForm();
- this.leaveHover();
- this.element.style.backgroundColor = this.originalBackground;
- Element.show(this.element);
- if (this.options.externalControl) {
- Element.show(this.options.externalControl);
- }
- this.editing = false;
- this.saving = false;
- this.oldInnerHTML = null;
- this.onLeaveEditMode();
- },
- onComplete: function(transport) {
- this.leaveEditMode();
- this.options.onComplete.bind(this)(transport, this.element);
- },
- onEnterEditMode: function() {},
- onLeaveEditMode: function() {},
- dispose: function() {
- if (this.oldInnerHTML) {
- this.element.innerHTML = this.oldInnerHTML;
- }
- this.leaveEditMode();
- Event.stopObserving(this.element, 'click', this.onclickListener);
- Event.stopObserving(this.element, 'mouseover', this.mouseoverListener);
- Event.stopObserving(this.element, 'mouseout', this.mouseoutListener);
- if (this.options.externalControl) {
- Event.stopObserving(this.options.externalControl, 'click', this.onclickListener);
- Event.stopObserving(this.options.externalControl, 'mouseover', this.mouseoverListener);
- Event.stopObserving(this.options.externalControl, 'mouseout', this.mouseoutListener);
- }
- }
-};
-
-Ajax.InPlaceCollectionEditor = Class.create();
-Object.extend(Ajax.InPlaceCollectionEditor.prototype, Ajax.InPlaceEditor.prototype);
-Object.extend(Ajax.InPlaceCollectionEditor.prototype, {
- createEditField: function() {
- if (!this.cached_selectTag) {
- var selectTag = document.createElement("select");
- var collection = this.options.collection || [];
- var optionTag;
- collection.each(function(e,i) {
- optionTag = document.createElement("option");
- optionTag.value = (e instanceof Array) ? e[0] : e;
- if((typeof this.options.value == 'undefined') &&
- ((e instanceof Array) ? this.element.innerHTML == e[1] : e == optionTag.value)) optionTag.selected = true;
- if(this.options.value==optionTag.value) optionTag.selected = true;
- optionTag.appendChild(document.createTextNode((e instanceof Array) ? e[1] : e));
- selectTag.appendChild(optionTag);
- }.bind(this));
- this.cached_selectTag = selectTag;
- }
-
- this.editField = this.cached_selectTag;
- if(this.options.loadTextURL) this.loadExternalText();
- this.form.appendChild(this.editField);
- this.options.callback = function(form, value) {
- return "value=" + encodeURIComponent(value);
- }
- }
-});
-
-// Delayed observer, like Form.Element.Observer,
-// but waits for delay after last key input
-// Ideal for live-search fields
-
-Form.Element.DelayedObserver = Class.create();
-Form.Element.DelayedObserver.prototype = {
- initialize: function(element, delay, callback) {
- this.delay = delay || 0.5;
- this.element = $(element);
- this.callback = callback;
- this.timer = null;
- this.lastValue = $F(this.element);
- Event.observe(this.element,'keyup',this.delayedListener.bindAsEventListener(this));
- },
- delayedListener: function(event) {
- if(this.lastValue == $F(this.element)) return;
- if(this.timer) clearTimeout(this.timer);
- this.timer = setTimeout(this.onTimerEvent.bind(this), this.delay * 1000);
- this.lastValue = $F(this.element);
- },
- onTimerEvent: function() {
- this.timer = null;
- this.callback(this.element, $F(this.element));
- }
-};
diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/public/javascripts/dragdrop.js b/vendor/plugins/has_many_polymorphs/test/integration/app/public/javascripts/dragdrop.js
deleted file mode 100644
index c71ddb82..00000000
--- a/vendor/plugins/has_many_polymorphs/test/integration/app/public/javascripts/dragdrop.js
+++ /dev/null
@@ -1,942 +0,0 @@
-// Copyright (c) 2005, 2006 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
-// (c) 2005, 2006 Sammi Williams (http://www.oriontransfer.co.nz, sammi@oriontransfer.co.nz)
-//
-// script.aculo.us is freely distributable under the terms of an MIT-style license.
-// For details, see the script.aculo.us web site: http://script.aculo.us/
-
-if(typeof Effect == 'undefined')
- throw("dragdrop.js requires including script.aculo.us' effects.js library");
-
-var Droppables = {
- drops: [],
-
- remove: function(element) {
- this.drops = this.drops.reject(function(d) { return d.element==$(element) });
- },
-
- add: function(element) {
- element = $(element);
- var options = Object.extend({
- greedy: true,
- hoverclass: null,
- tree: false
- }, arguments[1] || {});
-
- // cache containers
- if(options.containment) {
- options._containers = [];
- var containment = options.containment;
- if((typeof containment == 'object') &&
- (containment.constructor == Array)) {
- containment.each( function(c) { options._containers.push($(c)) });
- } else {
- options._containers.push($(containment));
- }
- }
-
- if(options.accept) options.accept = [options.accept].flatten();
-
- Element.makePositioned(element); // fix IE
- options.element = element;
-
- this.drops.push(options);
- },
-
- findDeepestChild: function(drops) {
- deepest = drops[0];
-
- for (i = 1; i < drops.length; ++i)
- if (Element.isParent(drops[i].element, deepest.element))
- deepest = drops[i];
-
- return deepest;
- },
-
- isContained: function(element, drop) {
- var containmentNode;
- if(drop.tree) {
- containmentNode = element.treeNode;
- } else {
- containmentNode = element.parentNode;
- }
- return drop._containers.detect(function(c) { return containmentNode == c });
- },
-
- isAffected: function(point, element, drop) {
- return (
- (drop.element!=element) &&
- ((!drop._containers) ||
- this.isContained(element, drop)) &&
- ((!drop.accept) ||
- (Element.classNames(element).detect(
- function(v) { return drop.accept.include(v) } ) )) &&
- Position.within(drop.element, point[0], point[1]) );
- },
-
- deactivate: function(drop) {
- if(drop.hoverclass)
- Element.removeClassName(drop.element, drop.hoverclass);
- this.last_active = null;
- },
-
- activate: function(drop) {
- if(drop.hoverclass)
- Element.addClassName(drop.element, drop.hoverclass);
- this.last_active = drop;
- },
-
- show: function(point, element) {
- if(!this.drops.length) return;
- var affected = [];
-
- if(this.last_active) this.deactivate(this.last_active);
- this.drops.each( function(drop) {
- if(Droppables.isAffected(point, element, drop))
- affected.push(drop);
- });
-
- if(affected.length>0) {
- drop = Droppables.findDeepestChild(affected);
- Position.within(drop.element, point[0], point[1]);
- if(drop.onHover)
- drop.onHover(element, drop.element, Position.overlap(drop.overlap, drop.element));
-
- Droppables.activate(drop);
- }
- },
-
- fire: function(event, element) {
- if(!this.last_active) return;
- Position.prepare();
-
- if (this.isAffected([Event.pointerX(event), Event.pointerY(event)], element, this.last_active))
- if (this.last_active.onDrop)
- this.last_active.onDrop(element, this.last_active.element, event);
- },
-
- reset: function() {
- if(this.last_active)
- this.deactivate(this.last_active);
- }
-}
-
-var Draggables = {
- drags: [],
- observers: [],
-
- register: function(draggable) {
- if(this.drags.length == 0) {
- this.eventMouseUp = this.endDrag.bindAsEventListener(this);
- this.eventMouseMove = this.updateDrag.bindAsEventListener(this);
- this.eventKeypress = this.keyPress.bindAsEventListener(this);
-
- Event.observe(document, "mouseup", this.eventMouseUp);
- Event.observe(document, "mousemove", this.eventMouseMove);
- Event.observe(document, "keypress", this.eventKeypress);
- }
- this.drags.push(draggable);
- },
-
- unregister: function(draggable) {
- this.drags = this.drags.reject(function(d) { return d==draggable });
- if(this.drags.length == 0) {
- Event.stopObserving(document, "mouseup", this.eventMouseUp);
- Event.stopObserving(document, "mousemove", this.eventMouseMove);
- Event.stopObserving(document, "keypress", this.eventKeypress);
- }
- },
-
- activate: function(draggable) {
- if(draggable.options.delay) {
- this._timeout = setTimeout(function() {
- Draggables._timeout = null;
- window.focus();
- Draggables.activeDraggable = draggable;
- }.bind(this), draggable.options.delay);
- } else {
- window.focus(); // allows keypress events if window isn't currently focused, fails for Safari
- this.activeDraggable = draggable;
- }
- },
-
- deactivate: function() {
- this.activeDraggable = null;
- },
-
- updateDrag: function(event) {
- if(!this.activeDraggable) return;
- var pointer = [Event.pointerX(event), Event.pointerY(event)];
- // Mozilla-based browsers fire successive mousemove events with
- // the same coordinates, prevent needless redrawing (moz bug?)
- if(this._lastPointer && (this._lastPointer.inspect() == pointer.inspect())) return;
- this._lastPointer = pointer;
-
- this.activeDraggable.updateDrag(event, pointer);
- },
-
- endDrag: function(event) {
- if(this._timeout) {
- clearTimeout(this._timeout);
- this._timeout = null;
- }
- if(!this.activeDraggable) return;
- this._lastPointer = null;
- this.activeDraggable.endDrag(event);
- this.activeDraggable = null;
- },
-
- keyPress: function(event) {
- if(this.activeDraggable)
- this.activeDraggable.keyPress(event);
- },
-
- addObserver: function(observer) {
- this.observers.push(observer);
- this._cacheObserverCallbacks();
- },
-
- removeObserver: function(element) { // element instead of observer fixes mem leaks
- this.observers = this.observers.reject( function(o) { return o.element==element });
- this._cacheObserverCallbacks();
- },
-
- notify: function(eventName, draggable, event) { // 'onStart', 'onEnd', 'onDrag'
- if(this[eventName+'Count'] > 0)
- this.observers.each( function(o) {
- if(o[eventName]) o[eventName](eventName, draggable, event);
- });
- if(draggable.options[eventName]) draggable.options[eventName](draggable, event);
- },
-
- _cacheObserverCallbacks: function() {
- ['onStart','onEnd','onDrag'].each( function(eventName) {
- Draggables[eventName+'Count'] = Draggables.observers.select(
- function(o) { return o[eventName]; }
- ).length;
- });
- }
-}
-
-/*--------------------------------------------------------------------------*/
-
-var Draggable = Class.create();
-Draggable._dragging = {};
-
-Draggable.prototype = {
- initialize: function(element) {
- var defaults = {
- handle: false,
- reverteffect: function(element, top_offset, left_offset) {
- var dur = Math.sqrt(Math.abs(top_offset^2)+Math.abs(left_offset^2))*0.02;
- new Effect.Move(element, { x: -left_offset, y: -top_offset, duration: dur,
- queue: {scope:'_draggable', position:'end'}
- });
- },
- endeffect: function(element) {
- var toOpacity = typeof element._opacity == 'number' ? element._opacity : 1.0;
- new Effect.Opacity(element, {duration:0.2, from:0.7, to:toOpacity,
- queue: {scope:'_draggable', position:'end'},
- afterFinish: function(){
- Draggable._dragging[element] = false
- }
- });
- },
- zindex: 1000,
- revert: false,
- scroll: false,
- scrollSensitivity: 20,
- scrollSpeed: 15,
- snap: false, // false, or xy or [x,y] or function(x,y){ return [x,y] }
- delay: 0
- };
-
- if(!arguments[1] || typeof arguments[1].endeffect == 'undefined')
- Object.extend(defaults, {
- starteffect: function(element) {
- element._opacity = Element.getOpacity(element);
- Draggable._dragging[element] = true;
- new Effect.Opacity(element, {duration:0.2, from:element._opacity, to:0.7});
- }
- });
-
- var options = Object.extend(defaults, arguments[1] || {});
-
- this.element = $(element);
-
- if(options.handle && (typeof options.handle == 'string'))
- this.handle = this.element.down('.'+options.handle, 0);
-
- if(!this.handle) this.handle = $(options.handle);
- if(!this.handle) this.handle = this.element;
-
- if(options.scroll && !options.scroll.scrollTo && !options.scroll.outerHTML) {
- options.scroll = $(options.scroll);
- this._isScrollChild = Element.childOf(this.element, options.scroll);
- }
-
- Element.makePositioned(this.element); // fix IE
-
- this.delta = this.currentDelta();
- this.options = options;
- this.dragging = false;
-
- this.eventMouseDown = this.initDrag.bindAsEventListener(this);
- Event.observe(this.handle, "mousedown", this.eventMouseDown);
-
- Draggables.register(this);
- },
-
- destroy: function() {
- Event.stopObserving(this.handle, "mousedown", this.eventMouseDown);
- Draggables.unregister(this);
- },
-
- currentDelta: function() {
- return([
- parseInt(Element.getStyle(this.element,'left') || '0'),
- parseInt(Element.getStyle(this.element,'top') || '0')]);
- },
-
- initDrag: function(event) {
- if(typeof Draggable._dragging[this.element] != 'undefined' &&
- Draggable._dragging[this.element]) return;
- if(Event.isLeftClick(event)) {
- // abort on form elements, fixes a Firefox issue
- var src = Event.element(event);
- if(src.tagName && (
- src.tagName=='INPUT' ||
- src.tagName=='SELECT' ||
- src.tagName=='OPTION' ||
- src.tagName=='BUTTON' ||
- src.tagName=='TEXTAREA')) return;
-
- var pointer = [Event.pointerX(event), Event.pointerY(event)];
- var pos = Position.cumulativeOffset(this.element);
- this.offset = [0,1].map( function(i) { return (pointer[i] - pos[i]) });
-
- Draggables.activate(this);
- Event.stop(event);
- }
- },
-
- startDrag: function(event) {
- this.dragging = true;
-
- if(this.options.zindex) {
- this.originalZ = parseInt(Element.getStyle(this.element,'z-index') || 0);
- this.element.style.zIndex = this.options.zindex;
- }
-
- if(this.options.ghosting) {
- this._clone = this.element.cloneNode(true);
- Position.absolutize(this.element);
- this.element.parentNode.insertBefore(this._clone, this.element);
- }
-
- if(this.options.scroll) {
- if (this.options.scroll == window) {
- var where = this._getWindowScroll(this.options.scroll);
- this.originalScrollLeft = where.left;
- this.originalScrollTop = where.top;
- } else {
- this.originalScrollLeft = this.options.scroll.scrollLeft;
- this.originalScrollTop = this.options.scroll.scrollTop;
- }
- }
-
- Draggables.notify('onStart', this, event);
-
- if(this.options.starteffect) this.options.starteffect(this.element);
- },
-
- updateDrag: function(event, pointer) {
- if(!this.dragging) this.startDrag(event);
- Position.prepare();
- Droppables.show(pointer, this.element);
- Draggables.notify('onDrag', this, event);
-
- this.draw(pointer);
- if(this.options.change) this.options.change(this);
-
- if(this.options.scroll) {
- this.stopScrolling();
-
- var p;
- if (this.options.scroll == window) {
- with(this._getWindowScroll(this.options.scroll)) { p = [ left, top, left+width, top+height ]; }
- } else {
- p = Position.page(this.options.scroll);
- p[0] += this.options.scroll.scrollLeft + Position.deltaX;
- p[1] += this.options.scroll.scrollTop + Position.deltaY;
- p.push(p[0]+this.options.scroll.offsetWidth);
- p.push(p[1]+this.options.scroll.offsetHeight);
- }
- var speed = [0,0];
- if(pointer[0] < (p[0]+this.options.scrollSensitivity)) speed[0] = pointer[0]-(p[0]+this.options.scrollSensitivity);
- if(pointer[1] < (p[1]+this.options.scrollSensitivity)) speed[1] = pointer[1]-(p[1]+this.options.scrollSensitivity);
- if(pointer[0] > (p[2]-this.options.scrollSensitivity)) speed[0] = pointer[0]-(p[2]-this.options.scrollSensitivity);
- if(pointer[1] > (p[3]-this.options.scrollSensitivity)) speed[1] = pointer[1]-(p[3]-this.options.scrollSensitivity);
- this.startScrolling(speed);
- }
-
- // fix AppleWebKit rendering
- if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0);
-
- Event.stop(event);
- },
-
- finishDrag: function(event, success) {
- this.dragging = false;
-
- if(this.options.ghosting) {
- Position.relativize(this.element);
- Element.remove(this._clone);
- this._clone = null;
- }
-
- if(success) Droppables.fire(event, this.element);
- Draggables.notify('onEnd', this, event);
-
- var revert = this.options.revert;
- if(revert && typeof revert == 'function') revert = revert(this.element);
-
- var d = this.currentDelta();
- if(revert && this.options.reverteffect) {
- this.options.reverteffect(this.element,
- d[1]-this.delta[1], d[0]-this.delta[0]);
- } else {
- this.delta = d;
- }
-
- if(this.options.zindex)
- this.element.style.zIndex = this.originalZ;
-
- if(this.options.endeffect)
- this.options.endeffect(this.element);
-
- Draggables.deactivate(this);
- Droppables.reset();
- },
-
- keyPress: function(event) {
- if(event.keyCode!=Event.KEY_ESC) return;
- this.finishDrag(event, false);
- Event.stop(event);
- },
-
- endDrag: function(event) {
- if(!this.dragging) return;
- this.stopScrolling();
- this.finishDrag(event, true);
- Event.stop(event);
- },
-
- draw: function(point) {
- var pos = Position.cumulativeOffset(this.element);
- if(this.options.ghosting) {
- var r = Position.realOffset(this.element);
- pos[0] += r[0] - Position.deltaX; pos[1] += r[1] - Position.deltaY;
- }
-
- var d = this.currentDelta();
- pos[0] -= d[0]; pos[1] -= d[1];
-
- if(this.options.scroll && (this.options.scroll != window && this._isScrollChild)) {
- pos[0] -= this.options.scroll.scrollLeft-this.originalScrollLeft;
- pos[1] -= this.options.scroll.scrollTop-this.originalScrollTop;
- }
-
- var p = [0,1].map(function(i){
- return (point[i]-pos[i]-this.offset[i])
- }.bind(this));
-
- if(this.options.snap) {
- if(typeof this.options.snap == 'function') {
- p = this.options.snap(p[0],p[1],this);
- } else {
- if(this.options.snap instanceof Array) {
- p = p.map( function(v, i) {
- return Math.round(v/this.options.snap[i])*this.options.snap[i] }.bind(this))
- } else {
- p = p.map( function(v) {
- return Math.round(v/this.options.snap)*this.options.snap }.bind(this))
- }
- }}
-
- var style = this.element.style;
- if((!this.options.constraint) || (this.options.constraint=='horizontal'))
- style.left = p[0] + "px";
- if((!this.options.constraint) || (this.options.constraint=='vertical'))
- style.top = p[1] + "px";
-
- if(style.visibility=="hidden") style.visibility = ""; // fix gecko rendering
- },
-
- stopScrolling: function() {
- if(this.scrollInterval) {
- clearInterval(this.scrollInterval);
- this.scrollInterval = null;
- Draggables._lastScrollPointer = null;
- }
- },
-
- startScrolling: function(speed) {
- if(!(speed[0] || speed[1])) return;
- this.scrollSpeed = [speed[0]*this.options.scrollSpeed,speed[1]*this.options.scrollSpeed];
- this.lastScrolled = new Date();
- this.scrollInterval = setInterval(this.scroll.bind(this), 10);
- },
-
- scroll: function() {
- var current = new Date();
- var delta = current - this.lastScrolled;
- this.lastScrolled = current;
- if(this.options.scroll == window) {
- with (this._getWindowScroll(this.options.scroll)) {
- if (this.scrollSpeed[0] || this.scrollSpeed[1]) {
- var d = delta / 1000;
- this.options.scroll.scrollTo( left + d*this.scrollSpeed[0], top + d*this.scrollSpeed[1] );
- }
- }
- } else {
- this.options.scroll.scrollLeft += this.scrollSpeed[0] * delta / 1000;
- this.options.scroll.scrollTop += this.scrollSpeed[1] * delta / 1000;
- }
-
- Position.prepare();
- Droppables.show(Draggables._lastPointer, this.element);
- Draggables.notify('onDrag', this);
- if (this._isScrollChild) {
- Draggables._lastScrollPointer = Draggables._lastScrollPointer || $A(Draggables._lastPointer);
- Draggables._lastScrollPointer[0] += this.scrollSpeed[0] * delta / 1000;
- Draggables._lastScrollPointer[1] += this.scrollSpeed[1] * delta / 1000;
- if (Draggables._lastScrollPointer[0] < 0)
- Draggables._lastScrollPointer[0] = 0;
- if (Draggables._lastScrollPointer[1] < 0)
- Draggables._lastScrollPointer[1] = 0;
- this.draw(Draggables._lastScrollPointer);
- }
-
- if(this.options.change) this.options.change(this);
- },
-
- _getWindowScroll: function(w) {
- var T, L, W, H;
- with (w.document) {
- if (w.document.documentElement && documentElement.scrollTop) {
- T = documentElement.scrollTop;
- L = documentElement.scrollLeft;
- } else if (w.document.body) {
- T = body.scrollTop;
- L = body.scrollLeft;
- }
- if (w.innerWidth) {
- W = w.innerWidth;
- H = w.innerHeight;
- } else if (w.document.documentElement && documentElement.clientWidth) {
- W = documentElement.clientWidth;
- H = documentElement.clientHeight;
- } else {
- W = body.offsetWidth;
- H = body.offsetHeight
- }
- }
- return { top: T, left: L, width: W, height: H };
- }
-}
-
-/*--------------------------------------------------------------------------*/
-
-var SortableObserver = Class.create();
-SortableObserver.prototype = {
- initialize: function(element, observer) {
- this.element = $(element);
- this.observer = observer;
- this.lastValue = Sortable.serialize(this.element);
- },
-
- onStart: function() {
- this.lastValue = Sortable.serialize(this.element);
- },
-
- onEnd: function() {
- Sortable.unmark();
- if(this.lastValue != Sortable.serialize(this.element))
- this.observer(this.element)
- }
-}
-
-var Sortable = {
- SERIALIZE_RULE: /^[^_\-](?:[A-Za-z0-9\-\_]*)[_](.*)$/,
-
- sortables: {},
-
- _findRootElement: function(element) {
- while (element.tagName != "BODY") {
- if(element.id && Sortable.sortables[element.id]) return element;
- element = element.parentNode;
- }
- },
-
- options: function(element) {
- element = Sortable._findRootElement($(element));
- if(!element) return;
- return Sortable.sortables[element.id];
- },
-
- destroy: function(element){
- var s = Sortable.options(element);
-
- if(s) {
- Draggables.removeObserver(s.element);
- s.droppables.each(function(d){ Droppables.remove(d) });
- s.draggables.invoke('destroy');
-
- delete Sortable.sortables[s.element.id];
- }
- },
-
- create: function(element) {
- element = $(element);
- var options = Object.extend({
- element: element,
- tag: 'li', // assumes li children, override with tag: 'tagname'
- dropOnEmpty: false,
- tree: false,
- treeTag: 'ul',
- overlap: 'vertical', // one of 'vertical', 'horizontal'
- constraint: 'vertical', // one of 'vertical', 'horizontal', false
- containment: element, // also takes array of elements (or id's); or false
- handle: false, // or a CSS class
- only: false,
- delay: 0,
- hoverclass: null,
- ghosting: false,
- scroll: false,
- scrollSensitivity: 20,
- scrollSpeed: 15,
- format: this.SERIALIZE_RULE,
- onChange: Prototype.emptyFunction,
- onUpdate: Prototype.emptyFunction
- }, arguments[1] || {});
-
- // clear any old sortable with same element
- this.destroy(element);
-
- // build options for the draggables
- var options_for_draggable = {
- revert: true,
- scroll: options.scroll,
- scrollSpeed: options.scrollSpeed,
- scrollSensitivity: options.scrollSensitivity,
- delay: options.delay,
- ghosting: options.ghosting,
- constraint: options.constraint,
- handle: options.handle };
-
- if(options.starteffect)
- options_for_draggable.starteffect = options.starteffect;
-
- if(options.reverteffect)
- options_for_draggable.reverteffect = options.reverteffect;
- else
- if(options.ghosting) options_for_draggable.reverteffect = function(element) {
- element.style.top = 0;
- element.style.left = 0;
- };
-
- if(options.endeffect)
- options_for_draggable.endeffect = options.endeffect;
-
- if(options.zindex)
- options_for_draggable.zindex = options.zindex;
-
- // build options for the droppables
- var options_for_droppable = {
- overlap: options.overlap,
- containment: options.containment,
- tree: options.tree,
- hoverclass: options.hoverclass,
- onHover: Sortable.onHover
- }
-
- var options_for_tree = {
- onHover: Sortable.onEmptyHover,
- overlap: options.overlap,
- containment: options.containment,
- hoverclass: options.hoverclass
- }
-
- // fix for gecko engine
- Element.cleanWhitespace(element);
-
- options.draggables = [];
- options.droppables = [];
-
- // drop on empty handling
- if(options.dropOnEmpty || options.tree) {
- Droppables.add(element, options_for_tree);
- options.droppables.push(element);
- }
-
- (this.findElements(element, options) || []).each( function(e) {
- // handles are per-draggable
- var handle = options.handle ?
- $(e).down('.'+options.handle,0) : e;
- options.draggables.push(
- new Draggable(e, Object.extend(options_for_draggable, { handle: handle })));
- Droppables.add(e, options_for_droppable);
- if(options.tree) e.treeNode = element;
- options.droppables.push(e);
- });
-
- if(options.tree) {
- (Sortable.findTreeElements(element, options) || []).each( function(e) {
- Droppables.add(e, options_for_tree);
- e.treeNode = element;
- options.droppables.push(e);
- });
- }
-
- // keep reference
- this.sortables[element.id] = options;
-
- // for onupdate
- Draggables.addObserver(new SortableObserver(element, options.onUpdate));
-
- },
-
- // return all suitable-for-sortable elements in a guaranteed order
- findElements: function(element, options) {
- return Element.findChildren(
- element, options.only, options.tree ? true : false, options.tag);
- },
-
- findTreeElements: function(element, options) {
- return Element.findChildren(
- element, options.only, options.tree ? true : false, options.treeTag);
- },
-
- onHover: function(element, dropon, overlap) {
- if(Element.isParent(dropon, element)) return;
-
- if(overlap > .33 && overlap < .66 && Sortable.options(dropon).tree) {
- return;
- } else if(overlap>0.5) {
- Sortable.mark(dropon, 'before');
- if(dropon.previousSibling != element) {
- var oldParentNode = element.parentNode;
- element.style.visibility = "hidden"; // fix gecko rendering
- dropon.parentNode.insertBefore(element, dropon);
- if(dropon.parentNode!=oldParentNode)
- Sortable.options(oldParentNode).onChange(element);
- Sortable.options(dropon.parentNode).onChange(element);
- }
- } else {
- Sortable.mark(dropon, 'after');
- var nextElement = dropon.nextSibling || null;
- if(nextElement != element) {
- var oldParentNode = element.parentNode;
- element.style.visibility = "hidden"; // fix gecko rendering
- dropon.parentNode.insertBefore(element, nextElement);
- if(dropon.parentNode!=oldParentNode)
- Sortable.options(oldParentNode).onChange(element);
- Sortable.options(dropon.parentNode).onChange(element);
- }
- }
- },
-
- onEmptyHover: function(element, dropon, overlap) {
- var oldParentNode = element.parentNode;
- var droponOptions = Sortable.options(dropon);
-
- if(!Element.isParent(dropon, element)) {
- var index;
-
- var children = Sortable.findElements(dropon, {tag: droponOptions.tag, only: droponOptions.only});
- var child = null;
-
- if(children) {
- var offset = Element.offsetSize(dropon, droponOptions.overlap) * (1.0 - overlap);
-
- for (index = 0; index < children.length; index += 1) {
- if (offset - Element.offsetSize (children[index], droponOptions.overlap) >= 0) {
- offset -= Element.offsetSize (children[index], droponOptions.overlap);
- } else if (offset - (Element.offsetSize (children[index], droponOptions.overlap) / 2) >= 0) {
- child = index + 1 < children.length ? children[index + 1] : null;
- break;
- } else {
- child = children[index];
- break;
- }
- }
- }
-
- dropon.insertBefore(element, child);
-
- Sortable.options(oldParentNode).onChange(element);
- droponOptions.onChange(element);
- }
- },
-
- unmark: function() {
- if(Sortable._marker) Sortable._marker.hide();
- },
-
- mark: function(dropon, position) {
- // mark on ghosting only
- var sortable = Sortable.options(dropon.parentNode);
- if(sortable && !sortable.ghosting) return;
-
- if(!Sortable._marker) {
- Sortable._marker =
- ($('dropmarker') || Element.extend(document.createElement('DIV'))).
- hide().addClassName('dropmarker').setStyle({position:'absolute'});
- document.getElementsByTagName("body").item(0).appendChild(Sortable._marker);
- }
- var offsets = Position.cumulativeOffset(dropon);
- Sortable._marker.setStyle({left: offsets[0]+'px', top: offsets[1] + 'px'});
-
- if(position=='after')
- if(sortable.overlap == 'horizontal')
- Sortable._marker.setStyle({left: (offsets[0]+dropon.clientWidth) + 'px'});
- else
- Sortable._marker.setStyle({top: (offsets[1]+dropon.clientHeight) + 'px'});
-
- Sortable._marker.show();
- },
-
- _tree: function(element, options, parent) {
- var children = Sortable.findElements(element, options) || [];
-
- for (var i = 0; i < children.length; ++i) {
- var match = children[i].id.match(options.format);
-
- if (!match) continue;
-
- var child = {
- id: encodeURIComponent(match ? match[1] : null),
- element: element,
- parent: parent,
- children: [],
- position: parent.children.length,
- container: $(children[i]).down(options.treeTag)
- }
-
- /* Get the element containing the children and recurse over it */
- if (child.container)
- this._tree(child.container, options, child)
-
- parent.children.push (child);
- }
-
- return parent;
- },
-
- tree: function(element) {
- element = $(element);
- var sortableOptions = this.options(element);
- var options = Object.extend({
- tag: sortableOptions.tag,
- treeTag: sortableOptions.treeTag,
- only: sortableOptions.only,
- name: element.id,
- format: sortableOptions.format
- }, arguments[1] || {});
-
- var root = {
- id: null,
- parent: null,
- children: [],
- container: element,
- position: 0
- }
-
- return Sortable._tree(element, options, root);
- },
-
- /* Construct a [i] index for a particular node */
- _constructIndex: function(node) {
- var index = '';
- do {
- if (node.id) index = '[' + node.position + ']' + index;
- } while ((node = node.parent) != null);
- return index;
- },
-
- sequence: function(element) {
- element = $(element);
- var options = Object.extend(this.options(element), arguments[1] || {});
-
- return $(this.findElements(element, options) || []).map( function(item) {
- return item.id.match(options.format) ? item.id.match(options.format)[1] : '';
- });
- },
-
- setSequence: function(element, new_sequence) {
- element = $(element);
- var options = Object.extend(this.options(element), arguments[2] || {});
-
- var nodeMap = {};
- this.findElements(element, options).each( function(n) {
- if (n.id.match(options.format))
- nodeMap[n.id.match(options.format)[1]] = [n, n.parentNode];
- n.parentNode.removeChild(n);
- });
-
- new_sequence.each(function(ident) {
- var n = nodeMap[ident];
- if (n) {
- n[1].appendChild(n[0]);
- delete nodeMap[ident];
- }
- });
- },
-
- serialize: function(element) {
- element = $(element);
- var options = Object.extend(Sortable.options(element), arguments[1] || {});
- var name = encodeURIComponent(
- (arguments[1] && arguments[1].name) ? arguments[1].name : element.id);
-
- if (options.tree) {
- return Sortable.tree(element, arguments[1]).children.map( function (item) {
- return [name + Sortable._constructIndex(item) + "[id]=" +
- encodeURIComponent(item.id)].concat(item.children.map(arguments.callee));
- }).flatten().join('&');
- } else {
- return Sortable.sequence(element, arguments[1]).map( function(item) {
- return name + "[]=" + encodeURIComponent(item);
- }).join('&');
- }
- }
-}
-
-// Returns true if child is contained within element
-Element.isParent = function(child, element) {
- if (!child.parentNode || child == element) return false;
- if (child.parentNode == element) return true;
- return Element.isParent(child.parentNode, element);
-}
-
-Element.findChildren = function(element, only, recursive, tagName) {
- if(!element.hasChildNodes()) return null;
- tagName = tagName.toUpperCase();
- if(only) only = [only].flatten();
- var elements = [];
- $A(element.childNodes).each( function(e) {
- if(e.tagName && e.tagName.toUpperCase()==tagName &&
- (!only || (Element.classNames(e).detect(function(v) { return only.include(v) }))))
- elements.push(e);
- if(recursive) {
- var grandchildren = Element.findChildren(e, only, recursive, tagName);
- if(grandchildren) elements.push(grandchildren);
- }
- });
-
- return (elements.length>0 ? elements.flatten() : []);
-}
-
-Element.offsetSize = function (element, type) {
- return element['offset' + ((type=='vertical' || type=='height') ? 'Height' : 'Width')];
-}
diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/public/javascripts/effects.js b/vendor/plugins/has_many_polymorphs/test/integration/app/public/javascripts/effects.js
deleted file mode 100644
index 3b02eda2..00000000
--- a/vendor/plugins/has_many_polymorphs/test/integration/app/public/javascripts/effects.js
+++ /dev/null
@@ -1,1088 +0,0 @@
-// Copyright (c) 2005, 2006 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
-// Contributors:
-// Justin Palmer (http://encytemedia.com/)
-// Mark Pilgrim (http://diveintomark.org/)
-// Martin Bialasinki
-//
-// script.aculo.us is freely distributable under the terms of an MIT-style license.
-// For details, see the script.aculo.us web site: http://script.aculo.us/
-
-// converts rgb() and #xxx to #xxxxxx format,
-// returns self (or first argument) if not convertable
-String.prototype.parseColor = function() {
- var color = '#';
- if(this.slice(0,4) == 'rgb(') {
- var cols = this.slice(4,this.length-1).split(',');
- var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3);
- } else {
- if(this.slice(0,1) == '#') {
- if(this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase();
- if(this.length==7) color = this.toLowerCase();
- }
- }
- return(color.length==7 ? color : (arguments[0] || this));
-}
-
-/*--------------------------------------------------------------------------*/
-
-Element.collectTextNodes = function(element) {
- return $A($(element).childNodes).collect( function(node) {
- return (node.nodeType==3 ? node.nodeValue :
- (node.hasChildNodes() ? Element.collectTextNodes(node) : ''));
- }).flatten().join('');
-}
-
-Element.collectTextNodesIgnoreClass = function(element, className) {
- return $A($(element).childNodes).collect( function(node) {
- return (node.nodeType==3 ? node.nodeValue :
- ((node.hasChildNodes() && !Element.hasClassName(node,className)) ?
- Element.collectTextNodesIgnoreClass(node, className) : ''));
- }).flatten().join('');
-}
-
-Element.setContentZoom = function(element, percent) {
- element = $(element);
- element.setStyle({fontSize: (percent/100) + 'em'});
- if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0);
- return element;
-}
-
-Element.getOpacity = function(element){
- element = $(element);
- var opacity;
- if (opacity = element.getStyle('opacity'))
- return parseFloat(opacity);
- if (opacity = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/))
- if(opacity[1]) return parseFloat(opacity[1]) / 100;
- return 1.0;
-}
-
-Element.setOpacity = function(element, value){
- element= $(element);
- if (value == 1){
- element.setStyle({ opacity:
- (/Gecko/.test(navigator.userAgent) && !/Konqueror|Safari|KHTML/.test(navigator.userAgent)) ?
- 0.999999 : 1.0 });
- if(/MSIE/.test(navigator.userAgent) && !window.opera)
- element.setStyle({filter: Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'')});
- } else {
- if(value < 0.00001) value = 0;
- element.setStyle({opacity: value});
- if(/MSIE/.test(navigator.userAgent) && !window.opera)
- element.setStyle(
- { filter: element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'') +
- 'alpha(opacity='+value*100+')' });
- }
- return element;
-}
-
-Element.getInlineOpacity = function(element){
- return $(element).style.opacity || '';
-}
-
-Element.forceRerendering = function(element) {
- try {
- element = $(element);
- var n = document.createTextNode(' ');
- element.appendChild(n);
- element.removeChild(n);
- } catch(e) { }
-};
-
-/*--------------------------------------------------------------------------*/
-
-Array.prototype.call = function() {
- var args = arguments;
- this.each(function(f){ f.apply(this, args) });
-}
-
-/*--------------------------------------------------------------------------*/
-
-var Effect = {
- _elementDoesNotExistError: {
- name: 'ElementDoesNotExistError',
- message: 'The specified DOM element does not exist, but is required for this effect to operate'
- },
- tagifyText: function(element) {
- if(typeof Builder == 'undefined')
- throw("Effect.tagifyText requires including script.aculo.us' builder.js library");
-
- var tagifyStyle = 'position:relative';
- if(/MSIE/.test(navigator.userAgent) && !window.opera) tagifyStyle += ';zoom:1';
-
- element = $(element);
- $A(element.childNodes).each( function(child) {
- if(child.nodeType==3) {
- child.nodeValue.toArray().each( function(character) {
- element.insertBefore(
- Builder.node('span',{style: tagifyStyle},
- character == ' ' ? String.fromCharCode(160) : character),
- child);
- });
- Element.remove(child);
- }
- });
- },
- multiple: function(element, effect) {
- var elements;
- if(((typeof element == 'object') ||
- (typeof element == 'function')) &&
- (element.length))
- elements = element;
- else
- elements = $(element).childNodes;
-
- var options = Object.extend({
- speed: 0.1,
- delay: 0.0
- }, arguments[2] || {});
- var masterDelay = options.delay;
-
- $A(elements).each( function(element, index) {
- new effect(element, Object.extend(options, { delay: index * options.speed + masterDelay }));
- });
- },
- PAIRS: {
- 'slide': ['SlideDown','SlideUp'],
- 'blind': ['BlindDown','BlindUp'],
- 'appear': ['Appear','Fade']
- },
- toggle: function(element, effect) {
- element = $(element);
- effect = (effect || 'appear').toLowerCase();
- var options = Object.extend({
- queue: { position:'end', scope:(element.id || 'global'), limit: 1 }
- }, arguments[2] || {});
- Effect[element.visible() ?
- Effect.PAIRS[effect][1] : Effect.PAIRS[effect][0]](element, options);
- }
-};
-
-var Effect2 = Effect; // deprecated
-
-/* ------------- transitions ------------- */
-
-Effect.Transitions = {
- linear: Prototype.K,
- sinoidal: function(pos) {
- return (-Math.cos(pos*Math.PI)/2) + 0.5;
- },
- reverse: function(pos) {
- return 1-pos;
- },
- flicker: function(pos) {
- return ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4;
- },
- wobble: function(pos) {
- return (-Math.cos(pos*Math.PI*(9*pos))/2) + 0.5;
- },
- pulse: function(pos, pulses) {
- pulses = pulses || 5;
- return (
- Math.round((pos % (1/pulses)) * pulses) == 0 ?
- ((pos * pulses * 2) - Math.floor(pos * pulses * 2)) :
- 1 - ((pos * pulses * 2) - Math.floor(pos * pulses * 2))
- );
- },
- none: function(pos) {
- return 0;
- },
- full: function(pos) {
- return 1;
- }
-};
-
-/* ------------- core effects ------------- */
-
-Effect.ScopedQueue = Class.create();
-Object.extend(Object.extend(Effect.ScopedQueue.prototype, Enumerable), {
- initialize: function() {
- this.effects = [];
- this.interval = null;
- },
- _each: function(iterator) {
- this.effects._each(iterator);
- },
- add: function(effect) {
- var timestamp = new Date().getTime();
-
- var position = (typeof effect.options.queue == 'string') ?
- effect.options.queue : effect.options.queue.position;
-
- switch(position) {
- case 'front':
- // move unstarted effects after this effect
- this.effects.findAll(function(e){ return e.state=='idle' }).each( function(e) {
- e.startOn += effect.finishOn;
- e.finishOn += effect.finishOn;
- });
- break;
- case 'with-last':
- timestamp = this.effects.pluck('startOn').max() || timestamp;
- break;
- case 'end':
- // start effect after last queued effect has finished
- timestamp = this.effects.pluck('finishOn').max() || timestamp;
- break;
- }
-
- effect.startOn += timestamp;
- effect.finishOn += timestamp;
-
- if(!effect.options.queue.limit || (this.effects.length < effect.options.queue.limit))
- this.effects.push(effect);
-
- if(!this.interval)
- this.interval = setInterval(this.loop.bind(this), 40);
- },
- remove: function(effect) {
- this.effects = this.effects.reject(function(e) { return e==effect });
- if(this.effects.length == 0) {
- clearInterval(this.interval);
- this.interval = null;
- }
- },
- loop: function() {
- var timePos = new Date().getTime();
- this.effects.invoke('loop', timePos);
- }
-});
-
-Effect.Queues = {
- instances: $H(),
- get: function(queueName) {
- if(typeof queueName != 'string') return queueName;
-
- if(!this.instances[queueName])
- this.instances[queueName] = new Effect.ScopedQueue();
-
- return this.instances[queueName];
- }
-}
-Effect.Queue = Effect.Queues.get('global');
-
-Effect.DefaultOptions = {
- transition: Effect.Transitions.sinoidal,
- duration: 1.0, // seconds
- fps: 25.0, // max. 25fps due to Effect.Queue implementation
- sync: false, // true for combining
- from: 0.0,
- to: 1.0,
- delay: 0.0,
- queue: 'parallel'
-}
-
-Effect.Base = function() {};
-Effect.Base.prototype = {
- position: null,
- start: function(options) {
- this.options = Object.extend(Object.extend({},Effect.DefaultOptions), options || {});
- this.currentFrame = 0;
- this.state = 'idle';
- this.startOn = this.options.delay*1000;
- this.finishOn = this.startOn + (this.options.duration*1000);
- this.event('beforeStart');
- if(!this.options.sync)
- Effect.Queues.get(typeof this.options.queue == 'string' ?
- 'global' : this.options.queue.scope).add(this);
- },
- loop: function(timePos) {
- if(timePos >= this.startOn) {
- if(timePos >= this.finishOn) {
- this.render(1.0);
- this.cancel();
- this.event('beforeFinish');
- if(this.finish) this.finish();
- this.event('afterFinish');
- return;
- }
- var pos = (timePos - this.startOn) / (this.finishOn - this.startOn);
- var frame = Math.round(pos * this.options.fps * this.options.duration);
- if(frame > this.currentFrame) {
- this.render(pos);
- this.currentFrame = frame;
- }
- }
- },
- render: function(pos) {
- if(this.state == 'idle') {
- this.state = 'running';
- this.event('beforeSetup');
- if(this.setup) this.setup();
- this.event('afterSetup');
- }
- if(this.state == 'running') {
- if(this.options.transition) pos = this.options.transition(pos);
- pos *= (this.options.to-this.options.from);
- pos += this.options.from;
- this.position = pos;
- this.event('beforeUpdate');
- if(this.update) this.update(pos);
- this.event('afterUpdate');
- }
- },
- cancel: function() {
- if(!this.options.sync)
- Effect.Queues.get(typeof this.options.queue == 'string' ?
- 'global' : this.options.queue.scope).remove(this);
- this.state = 'finished';
- },
- event: function(eventName) {
- if(this.options[eventName + 'Internal']) this.options[eventName + 'Internal'](this);
- if(this.options[eventName]) this.options[eventName](this);
- },
- inspect: function() {
- return '#' + html.stripScripts() + '
';
- depth = 2;
- break;
- case 'TR':
- div.innerHTML = '
';
- depth = 3;
- break;
- case 'TD':
- div.innerHTML = '' + html.stripScripts() + '
';
- depth = 4;
- }
- $A(element.childNodes).each(function(node){
- element.removeChild(node)
- });
- depth.times(function(){ div = div.firstChild });
-
- $A(div.childNodes).each(
- function(node){ element.appendChild(node) });
- } else {
- element.innerHTML = html.stripScripts();
- }
- setTimeout(function() {html.evalScripts()}, 10);
- return element;
- }
-};
-
-Object.extend(Element, Element.Methods);
-
-var _nativeExtensions = false;
-
-if(/Konqueror|Safari|KHTML/.test(navigator.userAgent))
- ['', 'Form', 'Input', 'TextArea', 'Select'].each(function(tag) {
- var className = 'HTML' + tag + 'Element';
- if(window[className]) return;
- var klass = window[className] = {};
- klass.prototype = document.createElement(tag ? tag.toLowerCase() : 'div').__proto__;
- });
-
-Element.addMethods = function(methods) {
- Object.extend(Element.Methods, methods || {});
-
- function copy(methods, destination, onlyIfAbsent) {
- onlyIfAbsent = onlyIfAbsent || false;
- var cache = Element.extend.cache;
- for (var property in methods) {
- var value = methods[property];
- if (!onlyIfAbsent || !(property in destination))
- destination[property] = cache.findOrStore(value);
- }
- }
-
- if (typeof HTMLElement != 'undefined') {
- copy(Element.Methods, HTMLElement.prototype);
- copy(Element.Methods.Simulated, HTMLElement.prototype, true);
- copy(Form.Methods, HTMLFormElement.prototype);
- [HTMLInputElement, HTMLTextAreaElement, HTMLSelectElement].each(function(klass) {
- copy(Form.Element.Methods, klass.prototype);
- });
- _nativeExtensions = true;
- }
-}
-
-var Toggle = new Object();
-Toggle.display = Element.toggle;
-
-/*--------------------------------------------------------------------------*/
-
-Abstract.Insertion = function(adjacency) {
- this.adjacency = adjacency;
-}
-
-Abstract.Insertion.prototype = {
- initialize: function(element, content) {
- this.element = $(element);
- this.content = content.stripScripts();
-
- if (this.adjacency && this.element.insertAdjacentHTML) {
- try {
- this.element.insertAdjacentHTML(this.adjacency, this.content);
- } catch (e) {
- var tagName = this.element.tagName.toUpperCase();
- if (['TBODY', 'TR'].include(tagName)) {
- this.insertContent(this.contentFromAnonymousTable());
- } else {
- throw e;
- }
- }
- } else {
- this.range = this.element.ownerDocument.createRange();
- if (this.initializeRange) this.initializeRange();
- this.insertContent([this.range.createContextualFragment(this.content)]);
- }
-
- setTimeout(function() {content.evalScripts()}, 10);
- },
-
- contentFromAnonymousTable: function() {
- var div = document.createElement('div');
- div.innerHTML = '' + html.stripScripts() + ' ' + this.content + '
';
- return $A(div.childNodes[0].childNodes[0].childNodes);
- }
-}
-
-var Insertion = new Object();
-
-Insertion.Before = Class.create();
-Insertion.Before.prototype = Object.extend(new Abstract.Insertion('beforeBegin'), {
- initializeRange: function() {
- this.range.setStartBefore(this.element);
- },
-
- insertContent: function(fragments) {
- fragments.each((function(fragment) {
- this.element.parentNode.insertBefore(fragment, this.element);
- }).bind(this));
- }
-});
-
-Insertion.Top = Class.create();
-Insertion.Top.prototype = Object.extend(new Abstract.Insertion('afterBegin'), {
- initializeRange: function() {
- this.range.selectNodeContents(this.element);
- this.range.collapse(true);
- },
-
- insertContent: function(fragments) {
- fragments.reverse(false).each((function(fragment) {
- this.element.insertBefore(fragment, this.element.firstChild);
- }).bind(this));
- }
-});
-
-Insertion.Bottom = Class.create();
-Insertion.Bottom.prototype = Object.extend(new Abstract.Insertion('beforeEnd'), {
- initializeRange: function() {
- this.range.selectNodeContents(this.element);
- this.range.collapse(this.element);
- },
-
- insertContent: function(fragments) {
- fragments.each((function(fragment) {
- this.element.appendChild(fragment);
- }).bind(this));
- }
-});
-
-Insertion.After = Class.create();
-Insertion.After.prototype = Object.extend(new Abstract.Insertion('afterEnd'), {
- initializeRange: function() {
- this.range.setStartAfter(this.element);
- },
-
- insertContent: function(fragments) {
- fragments.each((function(fragment) {
- this.element.parentNode.insertBefore(fragment,
- this.element.nextSibling);
- }).bind(this));
- }
-});
-
-/*--------------------------------------------------------------------------*/
-
-Element.ClassNames = Class.create();
-Element.ClassNames.prototype = {
- initialize: function(element) {
- this.element = $(element);
- },
-
- _each: function(iterator) {
- this.element.className.split(/\s+/).select(function(name) {
- return name.length > 0;
- })._each(iterator);
- },
-
- set: function(className) {
- this.element.className = className;
- },
-
- add: function(classNameToAdd) {
- if (this.include(classNameToAdd)) return;
- this.set($A(this).concat(classNameToAdd).join(' '));
- },
-
- remove: function(classNameToRemove) {
- if (!this.include(classNameToRemove)) return;
- this.set($A(this).without(classNameToRemove).join(' '));
- },
-
- toString: function() {
- return $A(this).join(' ');
- }
-};
-
-Object.extend(Element.ClassNames.prototype, Enumerable);
-var Selector = Class.create();
-Selector.prototype = {
- initialize: function(expression) {
- this.params = {classNames: []};
- this.expression = expression.toString().strip();
- this.parseExpression();
- this.compileMatcher();
- },
-
- parseExpression: function() {
- function abort(message) { throw 'Parse error in selector: ' + message; }
-
- if (this.expression == '') abort('empty expression');
-
- var params = this.params, expr = this.expression, match, modifier, clause, rest;
- while (match = expr.match(/^(.*)\[([a-z0-9_:-]+?)(?:([~\|!]?=)(?:"([^"]*)"|([^\]\s]*)))?\]$/i)) {
- params.attributes = params.attributes || [];
- params.attributes.push({name: match[2], operator: match[3], value: match[4] || match[5] || ''});
- expr = match[1];
- }
-
- if (expr == '*') return this.params.wildcard = true;
-
- while (match = expr.match(/^([^a-z0-9_-])?([a-z0-9_-]+)(.*)/i)) {
- modifier = match[1], clause = match[2], rest = match[3];
- switch (modifier) {
- case '#': params.id = clause; break;
- case '.': params.classNames.push(clause); break;
- case '':
- case undefined: params.tagName = clause.toUpperCase(); break;
- default: abort(expr.inspect());
- }
- expr = rest;
- }
-
- if (expr.length > 0) abort(expr.inspect());
- },
-
- buildMatchExpression: function() {
- var params = this.params, conditions = [], clause;
-
- if (params.wildcard)
- conditions.push('true');
- if (clause = params.id)
- conditions.push('element.readAttribute("id") == ' + clause.inspect());
- if (clause = params.tagName)
- conditions.push('element.tagName.toUpperCase() == ' + clause.inspect());
- if ((clause = params.classNames).length > 0)
- for (var i = 0, length = clause.length; i < length; i++)
- conditions.push('element.hasClassName(' + clause[i].inspect() + ')');
- if (clause = params.attributes) {
- clause.each(function(attribute) {
- var value = 'element.readAttribute(' + attribute.name.inspect() + ')';
- var splitValueBy = function(delimiter) {
- return value + ' && ' + value + '.split(' + delimiter.inspect() + ')';
- }
-
- switch (attribute.operator) {
- case '=': conditions.push(value + ' == ' + attribute.value.inspect()); break;
- case '~=': conditions.push(splitValueBy(' ') + '.include(' + attribute.value.inspect() + ')'); break;
- case '|=': conditions.push(
- splitValueBy('-') + '.first().toUpperCase() == ' + attribute.value.toUpperCase().inspect()
- ); break;
- case '!=': conditions.push(value + ' != ' + attribute.value.inspect()); break;
- case '':
- case undefined: conditions.push('element.hasAttribute(' + attribute.name.inspect() + ')'); break;
- default: throw 'Unknown operator ' + attribute.operator + ' in selector';
- }
- });
- }
-
- return conditions.join(' && ');
- },
-
- compileMatcher: function() {
- this.match = new Function('element', 'if (!element.tagName) return false; \
- element = $(element); \
- return ' + this.buildMatchExpression());
- },
-
- findElements: function(scope) {
- var element;
-
- if (element = $(this.params.id))
- if (this.match(element))
- if (!scope || Element.childOf(element, scope))
- return [element];
-
- scope = (scope || document).getElementsByTagName(this.params.tagName || '*');
-
- var results = [];
- for (var i = 0, length = scope.length; i < length; i++)
- if (this.match(element = scope[i]))
- results.push(Element.extend(element));
-
- return results;
- },
-
- toString: function() {
- return this.expression;
- }
-}
-
-Object.extend(Selector, {
- matchElements: function(elements, expression) {
- var selector = new Selector(expression);
- return elements.select(selector.match.bind(selector)).map(Element.extend);
- },
-
- findElement: function(elements, expression, index) {
- if (typeof expression == 'number') index = expression, expression = false;
- return Selector.matchElements(elements, expression || '*')[index || 0];
- },
-
- findChildElements: function(element, expressions) {
- return expressions.map(function(expression) {
- return expression.match(/[^\s"]+(?:"[^"]*"[^\s"]+)*/g).inject([null], function(results, expr) {
- var selector = new Selector(expr);
- return results.inject([], function(elements, result) {
- return elements.concat(selector.findElements(result || element));
- });
- });
- }).flatten();
- }
-});
-
-function $$() {
- return Selector.findChildElements(document, $A(arguments));
-}
-var Form = {
- reset: function(form) {
- $(form).reset();
- return form;
- },
-
- serializeElements: function(elements, getHash) {
- var data = elements.inject({}, function(result, element) {
- if (!element.disabled && element.name) {
- var key = element.name, value = $(element).getValue();
- if (value != undefined) {
- if (result[key]) {
- if (result[key].constructor != Array) result[key] = [result[key]];
- result[key].push(value);
- }
- else result[key] = value;
- }
- }
- return result;
- });
-
- return getHash ? data : Hash.toQueryString(data);
- }
-};
-
-Form.Methods = {
- serialize: function(form, getHash) {
- return Form.serializeElements(Form.getElements(form), getHash);
- },
-
- getElements: function(form) {
- return $A($(form).getElementsByTagName('*')).inject([],
- function(elements, child) {
- if (Form.Element.Serializers[child.tagName.toLowerCase()])
- elements.push(Element.extend(child));
- return elements;
- }
- );
- },
-
- getInputs: function(form, typeName, name) {
- form = $(form);
- var inputs = form.getElementsByTagName('input');
-
- if (!typeName && !name) return $A(inputs).map(Element.extend);
-
- for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) {
- var input = inputs[i];
- if ((typeName && input.type != typeName) || (name && input.name != name))
- continue;
- matchingInputs.push(Element.extend(input));
- }
-
- return matchingInputs;
- },
-
- disable: function(form) {
- form = $(form);
- form.getElements().each(function(element) {
- element.blur();
- element.disabled = 'true';
- });
- return form;
- },
-
- enable: function(form) {
- form = $(form);
- form.getElements().each(function(element) {
- element.disabled = '';
- });
- return form;
- },
-
- findFirstElement: function(form) {
- return $(form).getElements().find(function(element) {
- return element.type != 'hidden' && !element.disabled &&
- ['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
- });
- },
-
- focusFirstElement: function(form) {
- form = $(form);
- form.findFirstElement().activate();
- return form;
- }
-}
-
-Object.extend(Form, Form.Methods);
-
-/*--------------------------------------------------------------------------*/
-
-Form.Element = {
- focus: function(element) {
- $(element).focus();
- return element;
- },
-
- select: function(element) {
- $(element).select();
- return element;
- }
-}
-
-Form.Element.Methods = {
- serialize: function(element) {
- element = $(element);
- if (!element.disabled && element.name) {
- var value = element.getValue();
- if (value != undefined) {
- var pair = {};
- pair[element.name] = value;
- return Hash.toQueryString(pair);
- }
- }
- return '';
- },
-
- getValue: function(element) {
- element = $(element);
- var method = element.tagName.toLowerCase();
- return Form.Element.Serializers[method](element);
- },
-
- clear: function(element) {
- $(element).value = '';
- return element;
- },
-
- present: function(element) {
- return $(element).value != '';
- },
-
- activate: function(element) {
- element = $(element);
- element.focus();
- if (element.select && ( element.tagName.toLowerCase() != 'input' ||
- !['button', 'reset', 'submit'].include(element.type) ) )
- element.select();
- return element;
- },
-
- disable: function(element) {
- element = $(element);
- element.disabled = true;
- return element;
- },
-
- enable: function(element) {
- element = $(element);
- element.blur();
- element.disabled = false;
- return element;
- }
-}
-
-Object.extend(Form.Element, Form.Element.Methods);
-var Field = Form.Element;
-var $F = Form.Element.getValue;
-
-/*--------------------------------------------------------------------------*/
-
-Form.Element.Serializers = {
- input: function(element) {
- switch (element.type.toLowerCase()) {
- case 'checkbox':
- case 'radio':
- return Form.Element.Serializers.inputSelector(element);
- default:
- return Form.Element.Serializers.textarea(element);
- }
- },
-
- inputSelector: function(element) {
- return element.checked ? element.value : null;
- },
-
- textarea: function(element) {
- return element.value;
- },
-
- select: function(element) {
- return this[element.type == 'select-one' ?
- 'selectOne' : 'selectMany'](element);
- },
-
- selectOne: function(element) {
- var index = element.selectedIndex;
- return index >= 0 ? this.optionValue(element.options[index]) : null;
- },
-
- selectMany: function(element) {
- var values, length = element.length;
- if (!length) return null;
-
- for (var i = 0, values = []; i < length; i++) {
- var opt = element.options[i];
- if (opt.selected) values.push(this.optionValue(opt));
- }
- return values;
- },
-
- optionValue: function(opt) {
- // extend element because hasAttribute may not be native
- return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text;
- }
-}
-
-/*--------------------------------------------------------------------------*/
-
-Abstract.TimedObserver = function() {}
-Abstract.TimedObserver.prototype = {
- initialize: function(element, frequency, callback) {
- this.frequency = frequency;
- this.element = $(element);
- this.callback = callback;
-
- this.lastValue = this.getValue();
- this.registerCallback();
- },
-
- registerCallback: function() {
- setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
- },
-
- onTimerEvent: function() {
- var value = this.getValue();
- var changed = ('string' == typeof this.lastValue && 'string' == typeof value
- ? this.lastValue != value : String(this.lastValue) != String(value));
- if (changed) {
- this.callback(this.element, value);
- this.lastValue = value;
- }
- }
-}
-
-Form.Element.Observer = Class.create();
-Form.Element.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
- getValue: function() {
- return Form.Element.getValue(this.element);
- }
-});
-
-Form.Observer = Class.create();
-Form.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
- getValue: function() {
- return Form.serialize(this.element);
- }
-});
-
-/*--------------------------------------------------------------------------*/
-
-Abstract.EventObserver = function() {}
-Abstract.EventObserver.prototype = {
- initialize: function(element, callback) {
- this.element = $(element);
- this.callback = callback;
-
- this.lastValue = this.getValue();
- if (this.element.tagName.toLowerCase() == 'form')
- this.registerFormCallbacks();
- else
- this.registerCallback(this.element);
- },
-
- onElementEvent: function() {
- var value = this.getValue();
- if (this.lastValue != value) {
- this.callback(this.element, value);
- this.lastValue = value;
- }
- },
-
- registerFormCallbacks: function() {
- Form.getElements(this.element).each(this.registerCallback.bind(this));
- },
-
- registerCallback: function(element) {
- if (element.type) {
- switch (element.type.toLowerCase()) {
- case 'checkbox':
- case 'radio':
- Event.observe(element, 'click', this.onElementEvent.bind(this));
- break;
- default:
- Event.observe(element, 'change', this.onElementEvent.bind(this));
- break;
- }
- }
- }
-}
-
-Form.Element.EventObserver = Class.create();
-Form.Element.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
- getValue: function() {
- return Form.Element.getValue(this.element);
- }
-});
-
-Form.EventObserver = Class.create();
-Form.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
- getValue: function() {
- return Form.serialize(this.element);
- }
-});
-if (!window.Event) {
- var Event = new Object();
-}
-
-Object.extend(Event, {
- KEY_BACKSPACE: 8,
- KEY_TAB: 9,
- KEY_RETURN: 13,
- KEY_ESC: 27,
- KEY_LEFT: 37,
- KEY_UP: 38,
- KEY_RIGHT: 39,
- KEY_DOWN: 40,
- KEY_DELETE: 46,
- KEY_HOME: 36,
- KEY_END: 35,
- KEY_PAGEUP: 33,
- KEY_PAGEDOWN: 34,
-
- element: function(event) {
- return event.target || event.srcElement;
- },
-
- isLeftClick: function(event) {
- return (((event.which) && (event.which == 1)) ||
- ((event.button) && (event.button == 1)));
- },
-
- pointerX: function(event) {
- return event.pageX || (event.clientX +
- (document.documentElement.scrollLeft || document.body.scrollLeft));
- },
-
- pointerY: function(event) {
- return event.pageY || (event.clientY +
- (document.documentElement.scrollTop || document.body.scrollTop));
- },
-
- stop: function(event) {
- if (event.preventDefault) {
- event.preventDefault();
- event.stopPropagation();
- } else {
- event.returnValue = false;
- event.cancelBubble = true;
- }
- },
-
- // find the first node with the given tagName, starting from the
- // node the event was triggered on; traverses the DOM upwards
- findElement: function(event, tagName) {
- var element = Event.element(event);
- while (element.parentNode && (!element.tagName ||
- (element.tagName.toUpperCase() != tagName.toUpperCase())))
- element = element.parentNode;
- return element;
- },
-
- observers: false,
-
- _observeAndCache: function(element, name, observer, useCapture) {
- if (!this.observers) this.observers = [];
- if (element.addEventListener) {
- this.observers.push([element, name, observer, useCapture]);
- element.addEventListener(name, observer, useCapture);
- } else if (element.attachEvent) {
- this.observers.push([element, name, observer, useCapture]);
- element.attachEvent('on' + name, observer);
- }
- },
-
- unloadCache: function() {
- if (!Event.observers) return;
- for (var i = 0, length = Event.observers.length; i < length; i++) {
- Event.stopObserving.apply(this, Event.observers[i]);
- Event.observers[i][0] = null;
- }
- Event.observers = false;
- },
-
- observe: function(element, name, observer, useCapture) {
- element = $(element);
- useCapture = useCapture || false;
-
- if (name == 'keypress' &&
- (navigator.appVersion.match(/Konqueror|Safari|KHTML/)
- || element.attachEvent))
- name = 'keydown';
-
- Event._observeAndCache(element, name, observer, useCapture);
- },
-
- stopObserving: function(element, name, observer, useCapture) {
- element = $(element);
- useCapture = useCapture || false;
-
- if (name == 'keypress' &&
- (navigator.appVersion.match(/Konqueror|Safari|KHTML/)
- || element.detachEvent))
- name = 'keydown';
-
- if (element.removeEventListener) {
- element.removeEventListener(name, observer, useCapture);
- } else if (element.detachEvent) {
- try {
- element.detachEvent('on' + name, observer);
- } catch (e) {}
- }
- }
-});
-
-/* prevent memory leaks in IE */
-if (navigator.appVersion.match(/\bMSIE\b/))
- Event.observe(window, 'unload', Event.unloadCache, false);
-var Position = {
- // set to true if needed, warning: firefox performance problems
- // NOT neeeded for page scrolling, only if draggable contained in
- // scrollable elements
- includeScrollOffsets: false,
-
- // must be called before calling withinIncludingScrolloffset, every time the
- // page is scrolled
- prepare: function() {
- this.deltaX = window.pageXOffset
- || document.documentElement.scrollLeft
- || document.body.scrollLeft
- || 0;
- this.deltaY = window.pageYOffset
- || document.documentElement.scrollTop
- || document.body.scrollTop
- || 0;
- },
-
- realOffset: function(element) {
- var valueT = 0, valueL = 0;
- do {
- valueT += element.scrollTop || 0;
- valueL += element.scrollLeft || 0;
- element = element.parentNode;
- } while (element);
- return [valueL, valueT];
- },
-
- cumulativeOffset: function(element) {
- var valueT = 0, valueL = 0;
- do {
- valueT += element.offsetTop || 0;
- valueL += element.offsetLeft || 0;
- element = element.offsetParent;
- } while (element);
- return [valueL, valueT];
- },
-
- positionedOffset: function(element) {
- var valueT = 0, valueL = 0;
- do {
- valueT += element.offsetTop || 0;
- valueL += element.offsetLeft || 0;
- element = element.offsetParent;
- if (element) {
- if(element.tagName=='BODY') break;
- var p = Element.getStyle(element, 'position');
- if (p == 'relative' || p == 'absolute') break;
- }
- } while (element);
- return [valueL, valueT];
- },
-
- offsetParent: function(element) {
- if (element.offsetParent) return element.offsetParent;
- if (element == document.body) return element;
-
- while ((element = element.parentNode) && element != document.body)
- if (Element.getStyle(element, 'position') != 'static')
- return element;
-
- return document.body;
- },
-
- // caches x/y coordinate pair to use with overlap
- within: function(element, x, y) {
- if (this.includeScrollOffsets)
- return this.withinIncludingScrolloffsets(element, x, y);
- this.xcomp = x;
- this.ycomp = y;
- this.offset = this.cumulativeOffset(element);
-
- return (y >= this.offset[1] &&
- y < this.offset[1] + element.offsetHeight &&
- x >= this.offset[0] &&
- x < this.offset[0] + element.offsetWidth);
- },
-
- withinIncludingScrolloffsets: function(element, x, y) {
- var offsetcache = this.realOffset(element);
-
- this.xcomp = x + offsetcache[0] - this.deltaX;
- this.ycomp = y + offsetcache[1] - this.deltaY;
- this.offset = this.cumulativeOffset(element);
-
- return (this.ycomp >= this.offset[1] &&
- this.ycomp < this.offset[1] + element.offsetHeight &&
- this.xcomp >= this.offset[0] &&
- this.xcomp < this.offset[0] + element.offsetWidth);
- },
-
- // within must be called directly before
- overlap: function(mode, element) {
- if (!mode) return 0;
- if (mode == 'vertical')
- return ((this.offset[1] + element.offsetHeight) - this.ycomp) /
- element.offsetHeight;
- if (mode == 'horizontal')
- return ((this.offset[0] + element.offsetWidth) - this.xcomp) /
- element.offsetWidth;
- },
-
- page: function(forElement) {
- var valueT = 0, valueL = 0;
-
- var element = forElement;
- do {
- valueT += element.offsetTop || 0;
- valueL += element.offsetLeft || 0;
-
- // Safari fix
- if (element.offsetParent==document.body)
- if (Element.getStyle(element,'position')=='absolute') break;
-
- } while (element = element.offsetParent);
-
- element = forElement;
- do {
- if (!window.opera || element.tagName=='BODY') {
- valueT -= element.scrollTop || 0;
- valueL -= element.scrollLeft || 0;
- }
- } while (element = element.parentNode);
-
- return [valueL, valueT];
- },
-
- clone: function(source, target) {
- var options = Object.extend({
- setLeft: true,
- setTop: true,
- setWidth: true,
- setHeight: true,
- offsetTop: 0,
- offsetLeft: 0
- }, arguments[2] || {})
-
- // find page position of source
- source = $(source);
- var p = Position.page(source);
-
- // find coordinate system to use
- target = $(target);
- var delta = [0, 0];
- var parent = null;
- // delta [0,0] will do fine with position: fixed elements,
- // position:absolute needs offsetParent deltas
- if (Element.getStyle(target,'position') == 'absolute') {
- parent = Position.offsetParent(target);
- delta = Position.page(parent);
- }
-
- // correct by body offsets (fixes Safari)
- if (parent == document.body) {
- delta[0] -= document.body.offsetLeft;
- delta[1] -= document.body.offsetTop;
- }
-
- // set position
- if(options.setLeft) target.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px';
- if(options.setTop) target.style.top = (p[1] - delta[1] + options.offsetTop) + 'px';
- if(options.setWidth) target.style.width = source.offsetWidth + 'px';
- if(options.setHeight) target.style.height = source.offsetHeight + 'px';
- },
-
- absolutize: function(element) {
- element = $(element);
- if (element.style.position == 'absolute') return;
- Position.prepare();
-
- var offsets = Position.positionedOffset(element);
- var top = offsets[1];
- var left = offsets[0];
- var width = element.clientWidth;
- var height = element.clientHeight;
-
- element._originalLeft = left - parseFloat(element.style.left || 0);
- element._originalTop = top - parseFloat(element.style.top || 0);
- element._originalWidth = element.style.width;
- element._originalHeight = element.style.height;
-
- element.style.position = 'absolute';
- element.style.top = top + 'px';
- element.style.left = left + 'px';
- element.style.width = width + 'px';
- element.style.height = height + 'px';
- },
-
- relativize: function(element) {
- element = $(element);
- if (element.style.position == 'relative') return;
- Position.prepare();
-
- element.style.position = 'relative';
- var top = parseFloat(element.style.top || 0) - (element._originalTop || 0);
- var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0);
-
- element.style.top = top + 'px';
- element.style.left = left + 'px';
- element.style.height = element._originalHeight;
- element.style.width = element._originalWidth;
- }
-}
-
-// Safari returns margins on body which is incorrect if the child is absolutely
-// positioned. For performance reasons, redefine Position.cumulativeOffset for
-// KHTML/WebKit only.
-if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) {
- Position.cumulativeOffset = function(element) {
- var valueT = 0, valueL = 0;
- do {
- valueT += element.offsetTop || 0;
- valueL += element.offsetLeft || 0;
- if (element.offsetParent == document.body)
- if (Element.getStyle(element, 'position') == 'absolute') break;
-
- element = element.offsetParent;
- } while (element);
-
- return [valueL, valueT];
- }
-}
-
-Element.addMethods();
\ No newline at end of file
diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/public/robots.txt b/vendor/plugins/has_many_polymorphs/test/integration/app/public/robots.txt
deleted file mode 100644
index 4ab9e89f..00000000
--- a/vendor/plugins/has_many_polymorphs/test/integration/app/public/robots.txt
+++ /dev/null
@@ -1 +0,0 @@
-# See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file
\ No newline at end of file
diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/public/stylesheets/scaffold.css b/vendor/plugins/has_many_polymorphs/test/integration/app/public/stylesheets/scaffold.css
deleted file mode 100644
index 8f239a35..00000000
--- a/vendor/plugins/has_many_polymorphs/test/integration/app/public/stylesheets/scaffold.css
+++ /dev/null
@@ -1,74 +0,0 @@
-body { background-color: #fff; color: #333; }
-
-body, p, ol, ul, td {
- font-family: verdana, arial, helvetica, sans-serif;
- font-size: 13px;
- line-height: 18px;
-}
-
-pre {
- background-color: #eee;
- padding: 10px;
- font-size: 11px;
-}
-
-a { color: #000; }
-a:visited { color: #666; }
-a:hover { color: #fff; background-color:#000; }
-
-.fieldWithErrors {
- padding: 2px;
- background-color: red;
- display: table;
-}
-
-#errorExplanation {
- width: 400px;
- border: 2px solid red;
- padding: 7px;
- padding-bottom: 12px;
- margin-bottom: 20px;
- background-color: #f0f0f0;
-}
-
-#errorExplanation h2 {
- text-align: left;
- font-weight: bold;
- padding: 5px 5px 5px 15px;
- font-size: 12px;
- margin: -7px;
- background-color: #c00;
- color: #fff;
-}
-
-#errorExplanation p {
- color: #333;
- margin-bottom: 0;
- padding: 5px;
-}
-
-#errorExplanation ul li {
- font-size: 12px;
- list-style: square;
-}
-
-div.uploadStatus {
- margin: 5px;
-}
-
-div.progressBar {
- margin: 5px;
-}
-
-div.progressBar div.border {
- background-color: #fff;
- border: 1px solid grey;
- width: 100%;
-}
-
-div.progressBar div.background {
- background-color: #333;
- height: 18px;
- width: 0%;
-}
-
diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/script/about b/vendor/plugins/has_many_polymorphs/test/integration/app/script/about
deleted file mode 100755
index 7b07d46a..00000000
--- a/vendor/plugins/has_many_polymorphs/test/integration/app/script/about
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-require File.dirname(__FILE__) + '/../config/boot'
-require 'commands/about'
\ No newline at end of file
diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/script/breakpointer b/vendor/plugins/has_many_polymorphs/test/integration/app/script/breakpointer
deleted file mode 100755
index 64af76ed..00000000
--- a/vendor/plugins/has_many_polymorphs/test/integration/app/script/breakpointer
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-require File.dirname(__FILE__) + '/../config/boot'
-require 'commands/breakpointer'
\ No newline at end of file
diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/script/console b/vendor/plugins/has_many_polymorphs/test/integration/app/script/console
deleted file mode 100755
index 42f28f7d..00000000
--- a/vendor/plugins/has_many_polymorphs/test/integration/app/script/console
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-require File.dirname(__FILE__) + '/../config/boot'
-require 'commands/console'
\ No newline at end of file
diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/script/destroy b/vendor/plugins/has_many_polymorphs/test/integration/app/script/destroy
deleted file mode 100755
index fa0e6fcd..00000000
--- a/vendor/plugins/has_many_polymorphs/test/integration/app/script/destroy
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-require File.dirname(__FILE__) + '/../config/boot'
-require 'commands/destroy'
\ No newline at end of file
diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/script/generate b/vendor/plugins/has_many_polymorphs/test/integration/app/script/generate
deleted file mode 100755
index ef976e09..00000000
--- a/vendor/plugins/has_many_polymorphs/test/integration/app/script/generate
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-require File.dirname(__FILE__) + '/../config/boot'
-require 'commands/generate'
\ No newline at end of file
diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/script/performance/benchmarker b/vendor/plugins/has_many_polymorphs/test/integration/app/script/performance/benchmarker
deleted file mode 100755
index c842d35d..00000000
--- a/vendor/plugins/has_many_polymorphs/test/integration/app/script/performance/benchmarker
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-require File.dirname(__FILE__) + '/../../config/boot'
-require 'commands/performance/benchmarker'
diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/script/performance/profiler b/vendor/plugins/has_many_polymorphs/test/integration/app/script/performance/profiler
deleted file mode 100755
index d855ac8b..00000000
--- a/vendor/plugins/has_many_polymorphs/test/integration/app/script/performance/profiler
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-require File.dirname(__FILE__) + '/../../config/boot'
-require 'commands/performance/profiler'
diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/script/plugin b/vendor/plugins/has_many_polymorphs/test/integration/app/script/plugin
deleted file mode 100755
index 26ca64c0..00000000
--- a/vendor/plugins/has_many_polymorphs/test/integration/app/script/plugin
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-require File.dirname(__FILE__) + '/../config/boot'
-require 'commands/plugin'
\ No newline at end of file
diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/script/process/inspector b/vendor/plugins/has_many_polymorphs/test/integration/app/script/process/inspector
deleted file mode 100755
index bf25ad86..00000000
--- a/vendor/plugins/has_many_polymorphs/test/integration/app/script/process/inspector
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-require File.dirname(__FILE__) + '/../../config/boot'
-require 'commands/process/inspector'
diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/script/process/reaper b/vendor/plugins/has_many_polymorphs/test/integration/app/script/process/reaper
deleted file mode 100755
index c77f0453..00000000
--- a/vendor/plugins/has_many_polymorphs/test/integration/app/script/process/reaper
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-require File.dirname(__FILE__) + '/../../config/boot'
-require 'commands/process/reaper'
diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/script/process/spawner b/vendor/plugins/has_many_polymorphs/test/integration/app/script/process/spawner
deleted file mode 100755
index 7118f398..00000000
--- a/vendor/plugins/has_many_polymorphs/test/integration/app/script/process/spawner
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-require File.dirname(__FILE__) + '/../../config/boot'
-require 'commands/process/spawner'
diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/script/runner b/vendor/plugins/has_many_polymorphs/test/integration/app/script/runner
deleted file mode 100755
index ccc30f9d..00000000
--- a/vendor/plugins/has_many_polymorphs/test/integration/app/script/runner
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-require File.dirname(__FILE__) + '/../config/boot'
-require 'commands/runner'
\ No newline at end of file
diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/script/server b/vendor/plugins/has_many_polymorphs/test/integration/app/script/server
deleted file mode 100755
index dfabcb88..00000000
--- a/vendor/plugins/has_many_polymorphs/test/integration/app/script/server
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-require File.dirname(__FILE__) + '/../config/boot'
-require 'commands/server'
\ No newline at end of file
diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/test/fixtures/double_sti_parent_relationships.yml b/vendor/plugins/has_many_polymorphs/test/integration/app/test/fixtures/double_sti_parent_relationships.yml
deleted file mode 100644
index 5bf02933..00000000
--- a/vendor/plugins/has_many_polymorphs/test/integration/app/test/fixtures/double_sti_parent_relationships.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
-
-# one:
-# column: value
-#
-# two:
-# column: value
diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/test/fixtures/double_sti_parents.yml b/vendor/plugins/has_many_polymorphs/test/integration/app/test/fixtures/double_sti_parents.yml
deleted file mode 100644
index 5bf02933..00000000
--- a/vendor/plugins/has_many_polymorphs/test/integration/app/test/fixtures/double_sti_parents.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
-
-# one:
-# column: value
-#
-# two:
-# column: value
diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/test/fixtures/organic_substances.yml b/vendor/plugins/has_many_polymorphs/test/integration/app/test/fixtures/organic_substances.yml
deleted file mode 100644
index 123ef537..00000000
--- a/vendor/plugins/has_many_polymorphs/test/integration/app/test/fixtures/organic_substances.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-one:
- type: Bone
-
-two:
- type: Bone
diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/test/fixtures/single_sti_parent_relationships.yml b/vendor/plugins/has_many_polymorphs/test/integration/app/test/fixtures/single_sti_parent_relationships.yml
deleted file mode 100644
index 5bf02933..00000000
--- a/vendor/plugins/has_many_polymorphs/test/integration/app/test/fixtures/single_sti_parent_relationships.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
-
-# one:
-# column: value
-#
-# two:
-# column: value
diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/test/fixtures/single_sti_parents.yml b/vendor/plugins/has_many_polymorphs/test/integration/app/test/fixtures/single_sti_parents.yml
deleted file mode 100644
index 5bf02933..00000000
--- a/vendor/plugins/has_many_polymorphs/test/integration/app/test/fixtures/single_sti_parents.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
-
-# one:
-# column: value
-#
-# two:
-# column: value
diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/test/fixtures/sticks.yml b/vendor/plugins/has_many_polymorphs/test/integration/app/test/fixtures/sticks.yml
deleted file mode 100644
index 157d7472..00000000
--- a/vendor/plugins/has_many_polymorphs/test/integration/app/test/fixtures/sticks.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
-
-one:
- name: MyString
-
-two:
- name: MyString
diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/test/fixtures/stones.yml b/vendor/plugins/has_many_polymorphs/test/integration/app/test/fixtures/stones.yml
deleted file mode 100644
index 157d7472..00000000
--- a/vendor/plugins/has_many_polymorphs/test/integration/app/test/fixtures/stones.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
-
-one:
- name: MyString
-
-two:
- name: MyString
diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/test/functional/addresses_controller_test.rb b/vendor/plugins/has_many_polymorphs/test/integration/app/test/functional/addresses_controller_test.rb
deleted file mode 100644
index bf6d828a..00000000
--- a/vendor/plugins/has_many_polymorphs/test/integration/app/test/functional/addresses_controller_test.rb
+++ /dev/null
@@ -1,57 +0,0 @@
-require File.dirname(__FILE__) + '/../test_helper'
-require 'addresses_controller'
-
-# Re-raise errors caught by the controller.
-class AddressesController; def rescue_action(e) raise e end; end
-
-class AddressesControllerTest < ActiveSupport::TestCase
- fixtures :addresses
-
- def setup
- @controller = AddressesController.new
- @request = ActionController::TestRequest.new
- @response = ActionController::TestResponse.new
- end
-
- def test_should_get_index
- get :index
- assert_response :success
- assert assigns(:addresses)
- end
-
- def test_should_get_new
- get :new
- assert_response :success
- end
-
- def test_should_create_address
- assert_difference('Address.count') do
- post :create, :address => { :country_id => 1, :user_id => 1, :state_id => 1}
- end
-
- assert_redirected_to address_path(assigns(:address))
- end
-
- def test_should_show_address
- get :show, :id => 1
- assert_response :success
- end
-
- def test_should_get_edit
- get :edit, :id => 1
- assert_response :success
- end
-
- def test_should_update_address
- put :update, :id => 1, :address => { }
- assert_redirected_to address_path(assigns(:address))
- end
-
- def test_should_destroy_address
- assert_difference('Address.count', -1) do
- delete :destroy, :id => 1
- end
-
- assert_redirected_to addresses_path
- end
-end
diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/test/functional/bones_controller_test.rb b/vendor/plugins/has_many_polymorphs/test/integration/app/test/functional/bones_controller_test.rb
deleted file mode 100644
index fc0c7bd8..00000000
--- a/vendor/plugins/has_many_polymorphs/test/integration/app/test/functional/bones_controller_test.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-require File.dirname(__FILE__) + '/../test_helper'
-
-class BonesControllerTest < ActionController::TestCase
- # Replace this with your real tests.
- def test_truth
- assert true
- end
-end
diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/test/functional/sellers_controller_test.rb b/vendor/plugins/has_many_polymorphs/test/integration/app/test/functional/sellers_controller_test.rb
deleted file mode 100644
index 9fd6a948..00000000
--- a/vendor/plugins/has_many_polymorphs/test/integration/app/test/functional/sellers_controller_test.rb
+++ /dev/null
@@ -1,57 +0,0 @@
-require File.dirname(__FILE__) + '/../test_helper'
-require 'sellers_controller'
-
-# Re-raise errors caught by the controller.
-class SellersController; def rescue_action(e) raise e end; end
-
-class SellersControllerTest < ActiveSupport::TestCase
- fixtures :sellers
-
- def setup
- @controller = SellersController.new
- @request = ActionController::TestRequest.new
- @response = ActionController::TestResponse.new
- end
-
- def test_should_get_index
- get :index
- assert_response :success
- assert assigns(:sellers)
- end
-
- def test_should_get_new
- get :new
- assert_response :success
- end
-
- def test_should_create_seller
- assert_difference('Seller.count') do
- post :create, :seller => { }
- end
-
- assert_redirected_to seller_path(assigns(:seller))
- end
-
- def test_should_show_seller
- get :show, :id => 1
- assert_response :success
- end
-
- def test_should_get_edit
- get :edit, :id => 1
- assert_response :success
- end
-
- def test_should_update_seller
- put :update, :id => 1, :seller => { }
- assert_redirected_to seller_path(assigns(:seller))
- end
-
- def test_should_destroy_seller
- assert_difference('Seller.count', -1) do
- delete :destroy, :id => 1
- end
-
- assert_redirected_to sellers_path
- end
-end
diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/test/functional/states_controller_test.rb b/vendor/plugins/has_many_polymorphs/test/integration/app/test/functional/states_controller_test.rb
deleted file mode 100644
index c1d3b72d..00000000
--- a/vendor/plugins/has_many_polymorphs/test/integration/app/test/functional/states_controller_test.rb
+++ /dev/null
@@ -1,57 +0,0 @@
-require File.dirname(__FILE__) + '/../test_helper'
-require 'states_controller'
-
-# Re-raise errors caught by the controller.
-class StatesController; def rescue_action(e) raise e end; end
-
-class StatesControllerTest < ActiveSupport::TestCase
- fixtures :states
-
- def setup
- @controller = StatesController.new
- @request = ActionController::TestRequest.new
- @response = ActionController::TestResponse.new
- end
-
- def test_should_get_index
- get :index
- assert_response :success
- assert assigns(:states)
- end
-
- def test_should_get_new
- get :new
- assert_response :success
- end
-
- def test_should_create_state
- assert_difference('State.count') do
- post :create, :state => { }
- end
-
- assert_redirected_to state_path(assigns(:state))
- end
-
- def test_should_show_state
- get :show, :id => 1
- assert_response :success
- end
-
- def test_should_get_edit
- get :edit, :id => 1
- assert_response :success
- end
-
- def test_should_update_state
- put :update, :id => 1, :state => { }
- assert_redirected_to state_path(assigns(:state))
- end
-
- def test_should_destroy_state
- assert_difference('State.count', -1) do
- delete :destroy, :id => 1
- end
-
- assert_redirected_to states_path
- end
-end
diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/test/functional/users_controller_test.rb b/vendor/plugins/has_many_polymorphs/test/integration/app/test/functional/users_controller_test.rb
deleted file mode 100644
index 5ca62379..00000000
--- a/vendor/plugins/has_many_polymorphs/test/integration/app/test/functional/users_controller_test.rb
+++ /dev/null
@@ -1,57 +0,0 @@
-require File.dirname(__FILE__) + '/../test_helper'
-require 'users_controller'
-
-# Re-raise errors caught by the controller.
-class UsersController; def rescue_action(e) raise e end; end
-
-class UsersControllerTest < ActiveSupport::TestCase
- fixtures :users
-
- def setup
- @controller = UsersController.new
- @request = ActionController::TestRequest.new
- @response = ActionController::TestResponse.new
- end
-
- def test_should_get_index
- get :index
- assert_response :success
- assert assigns(:users)
- end
-
- def test_should_get_new
- get :new
- assert_response :success
- end
-
- def test_should_create_user
- assert_difference('User.count') do
- post :create, :user => { }
- end
-
- assert_redirected_to user_path(assigns(:user))
- end
-
- def test_should_show_user
- get :show, :id => 1
- assert_response :success
- end
-
- def test_should_get_edit
- get :edit, :id => 1
- assert_response :success
- end
-
- def test_should_update_user
- put :update, :id => 1, :user => { }
- assert_redirected_to user_path(assigns(:user))
- end
-
- def test_should_destroy_user
- assert_difference('User.count', -1) do
- delete :destroy, :id => 1
- end
-
- assert_redirected_to users_path
- end
-end
diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/test/test_helper.rb b/vendor/plugins/has_many_polymorphs/test/integration/app/test/test_helper.rb
deleted file mode 100644
index 0ab46bb2..00000000
--- a/vendor/plugins/has_many_polymorphs/test/integration/app/test/test_helper.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-ENV["RAILS_ENV"] = "development"
-require File.expand_path(File.dirname(__FILE__) + "/../config/environment")
-require 'test_help'
-
-class ActiveSupport::TestCase
- self.use_transactional_fixtures = true
- self.use_instantiated_fixtures = false
-end
diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/test/unit/bone_test.rb b/vendor/plugins/has_many_polymorphs/test/integration/app/test/unit/bone_test.rb
deleted file mode 100644
index 26d1371f..00000000
--- a/vendor/plugins/has_many_polymorphs/test/integration/app/test/unit/bone_test.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-require File.dirname(__FILE__) + '/../test_helper'
-
-class BoneTest < ActiveSupport::TestCase
- # Replace this with your real tests.
- def test_truth
- assert true
- end
-end
diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/test/unit/double_sti_parent_relationship_test.rb b/vendor/plugins/has_many_polymorphs/test/integration/app/test/unit/double_sti_parent_relationship_test.rb
deleted file mode 100644
index 50f8d3a8..00000000
--- a/vendor/plugins/has_many_polymorphs/test/integration/app/test/unit/double_sti_parent_relationship_test.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-require File.dirname(__FILE__) + '/../test_helper'
-
-class DoubleStiParentRelationshipTest < ActiveSupport::TestCase
- # Replace this with your real tests.
- def test_truth
- assert true
- end
-end
diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/test/unit/double_sti_parent_test.rb b/vendor/plugins/has_many_polymorphs/test/integration/app/test/unit/double_sti_parent_test.rb
deleted file mode 100644
index 9c0dbe72..00000000
--- a/vendor/plugins/has_many_polymorphs/test/integration/app/test/unit/double_sti_parent_test.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-require File.dirname(__FILE__) + '/../test_helper'
-
-class DoubleStiParentTest < ActiveSupport::TestCase
- # Replace this with your real tests.
- def test_truth
- assert true
- end
-end
diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/test/unit/organic_substance_test.rb b/vendor/plugins/has_many_polymorphs/test/integration/app/test/unit/organic_substance_test.rb
deleted file mode 100644
index 20d0d963..00000000
--- a/vendor/plugins/has_many_polymorphs/test/integration/app/test/unit/organic_substance_test.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-require File.dirname(__FILE__) + '/../test_helper'
-
-class OrganicSubstanceTest < ActiveSupport::TestCase
- # Replace this with your real tests.
- def test_truth
- assert true
- end
-end
diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/test/unit/single_sti_parent_relationship_test.rb b/vendor/plugins/has_many_polymorphs/test/integration/app/test/unit/single_sti_parent_relationship_test.rb
deleted file mode 100644
index 184209d7..00000000
--- a/vendor/plugins/has_many_polymorphs/test/integration/app/test/unit/single_sti_parent_relationship_test.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-require File.dirname(__FILE__) + '/../test_helper'
-
-class SingleStiParentRelationshipTest < ActiveSupport::TestCase
- # Replace this with your real tests.
- def test_truth
- assert true
- end
-end
diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/test/unit/single_sti_parent_test.rb b/vendor/plugins/has_many_polymorphs/test/integration/app/test/unit/single_sti_parent_test.rb
deleted file mode 100644
index 43d38070..00000000
--- a/vendor/plugins/has_many_polymorphs/test/integration/app/test/unit/single_sti_parent_test.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-require File.dirname(__FILE__) + '/../test_helper'
-
-class SingleStiParentTest < ActiveSupport::TestCase
- # Replace this with your real tests.
- def test_truth
- assert true
- end
-end
diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/test/unit/stick_test.rb b/vendor/plugins/has_many_polymorphs/test/integration/app/test/unit/stick_test.rb
deleted file mode 100644
index f21868a7..00000000
--- a/vendor/plugins/has_many_polymorphs/test/integration/app/test/unit/stick_test.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-require File.dirname(__FILE__) + '/../test_helper'
-
-class StickTest < ActiveSupport::TestCase
- # Replace this with your real tests.
- def test_truth
- assert true
- end
-end
diff --git a/vendor/plugins/has_many_polymorphs/test/integration/app/test/unit/stone_test.rb b/vendor/plugins/has_many_polymorphs/test/integration/app/test/unit/stone_test.rb
deleted file mode 100644
index b6705739..00000000
--- a/vendor/plugins/has_many_polymorphs/test/integration/app/test/unit/stone_test.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-require File.dirname(__FILE__) + '/../test_helper'
-
-class StoneTest < ActiveSupport::TestCase
- # Replace this with your real tests.
- def test_truth
- assert true
- end
-end
diff --git a/vendor/plugins/has_many_polymorphs/test/integration/server_test.rb b/vendor/plugins/has_many_polymorphs/test/integration/server_test.rb
deleted file mode 100644
index 724dd8ab..00000000
--- a/vendor/plugins/has_many_polymorphs/test/integration/server_test.rb
+++ /dev/null
@@ -1,43 +0,0 @@
-
-require "#{File.dirname(__FILE__)}/../test_helper"
-require 'open-uri'
-
-# Start the server
-
-class ServerTest < ActiveSupport::TestCase
-
- PORT = 43040
- URL = "http://localhost:#{PORT}/"
-
- def setup
- @pid = Process.fork do
- Dir.chdir RAILS_ROOT do
- # print "S"
- exec("script/server -p #{PORT} &> #{LOG}")
- end
- end
- sleep(5)
- end
-
- def teardown
- # Process.kill(9, @pid) doesn't work because Mongrel has double-forked itself away
- `ps awx | grep #{PORT} | grep -v grep | awk '{print $1}'`.split("\n").each do |pid|
- system("kill -9 #{pid}")
- # print "K"
- end
- sleep(2)
- @pid = nil
- end
-
- def test_association_reloading
- assert_match(/Bones: index/, open(URL + 'bones').read)
- assert_match(/Bones: index/, open(URL + 'bones').read)
- assert_match(/Bones: index/, open(URL + 'bones').read)
- assert_match(/Bones: index/, open(URL + 'bones').read)
- end
-
- def test_verify_autoload_gets_invoked_in_console
- # XXX Probably can use script/runner to test this
- end
-
-end
diff --git a/vendor/plugins/has_many_polymorphs/test/models/aquatic/fish.rb b/vendor/plugins/has_many_polymorphs/test/models/aquatic/fish.rb
deleted file mode 100644
index 204642e9..00000000
--- a/vendor/plugins/has_many_polymorphs/test/models/aquatic/fish.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class Aquatic::Fish < ActiveRecord::Base
- # set_table_name "fish"
- # attr_accessor :after_find_test, :after_initialize_test
-end
-
diff --git a/vendor/plugins/has_many_polymorphs/test/models/aquatic/pupils_whale.rb b/vendor/plugins/has_many_polymorphs/test/models/aquatic/pupils_whale.rb
deleted file mode 100644
index ae4cbc18..00000000
--- a/vendor/plugins/has_many_polymorphs/test/models/aquatic/pupils_whale.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-
-class Aquatic::PupilsWhale < ActiveRecord::Base
- set_table_name "little_whale_pupils"
- belongs_to :whale, :class_name => "Aquatic::Whale", :foreign_key => "whale_id"
- belongs_to :aquatic_pupil, :polymorphic => true
-end
-
diff --git a/vendor/plugins/has_many_polymorphs/test/models/aquatic/whale.rb b/vendor/plugins/has_many_polymorphs/test/models/aquatic/whale.rb
deleted file mode 100644
index 0ca1b7fb..00000000
--- a/vendor/plugins/has_many_polymorphs/test/models/aquatic/whale.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-# see http://dev.rubyonrails.org/ticket/5935
-module Aquatic; end
-require 'aquatic/fish'
-require 'aquatic/pupils_whale'
-
-class Aquatic::Whale < ActiveRecord::Base
- # set_table_name "whales"
-
- has_many_polymorphs(:aquatic_pupils, :from => [:dogs, :"aquatic/fish"],
- :through => "aquatic/pupils_whales") do
- def a_method
- :correct_block_result
- end
- end
-end
diff --git a/vendor/plugins/has_many_polymorphs/test/models/beautiful_fight_relationship.rb b/vendor/plugins/has_many_polymorphs/test/models/beautiful_fight_relationship.rb
deleted file mode 100644
index b678c982..00000000
--- a/vendor/plugins/has_many_polymorphs/test/models/beautiful_fight_relationship.rb
+++ /dev/null
@@ -1,26 +0,0 @@
-
-require 'extension_module'
-
-class BeautifulFightRelationship < ActiveRecord::Base
- set_table_name 'keep_your_enemies_close'
-
- belongs_to :enemy, :polymorphic => true
- belongs_to :protector, :polymorphic => true
- # polymorphic relationships with column names different from the relationship name
- # are not supported by Rails
-
- acts_as_double_polymorphic_join :enemies => [:dogs, :kittens, :frogs],
- :protectors => [:wild_boars, :kittens, :"aquatic/fish", :dogs],
- :enemies_extend => [ExtensionModule, proc {}],
- :protectors_extend => proc {
- def a_method
- :correct_proc_result
- end
- },
- :join_extend => proc {
- def a_method
- :correct_join_result
- end
- }
-end
-
diff --git a/vendor/plugins/has_many_polymorphs/test/models/canine.rb b/vendor/plugins/has_many_polymorphs/test/models/canine.rb
deleted file mode 100644
index b0010160..00000000
--- a/vendor/plugins/has_many_polymorphs/test/models/canine.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-class Canine < ActiveRecord::Base
- self.abstract_class = true
-
- def an_abstract_method
- :correct_abstract_method_response
- end
-
-end
-
diff --git a/vendor/plugins/has_many_polymorphs/test/models/cat.rb b/vendor/plugins/has_many_polymorphs/test/models/cat.rb
deleted file mode 100644
index 0c99ff08..00000000
--- a/vendor/plugins/has_many_polymorphs/test/models/cat.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class Cat < ActiveRecord::Base
- # STI base class
- self.inheritance_column = 'cat_type'
-end
-
diff --git a/vendor/plugins/has_many_polymorphs/test/models/dog.rb b/vendor/plugins/has_many_polymorphs/test/models/dog.rb
deleted file mode 100644
index 7f027237..00000000
--- a/vendor/plugins/has_many_polymorphs/test/models/dog.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-
-require 'canine'
-
-class Dog < Canine
- attr_accessor :after_find_test, :after_initialize_test
- set_table_name "bow_wows"
-
- def after_find
- @after_find_test = true
-# puts "After find called on #{name}."
- end
-
- def after_initialize
- @after_initialize_test = true
- end
-
-end
-
diff --git a/vendor/plugins/has_many_polymorphs/test/models/eaters_foodstuff.rb b/vendor/plugins/has_many_polymorphs/test/models/eaters_foodstuff.rb
deleted file mode 100644
index 99d0eac7..00000000
--- a/vendor/plugins/has_many_polymorphs/test/models/eaters_foodstuff.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-
-class EatersFoodstuff < ActiveRecord::Base
- belongs_to :foodstuff, :class_name => "Petfood", :foreign_key => "foodstuff_id"
- belongs_to :eater, :polymorphic => true
-
- before_save { |record| record.some_attribute = 3 }
-end
-
diff --git a/vendor/plugins/has_many_polymorphs/test/models/frog.rb b/vendor/plugins/has_many_polymorphs/test/models/frog.rb
deleted file mode 100644
index 5a0f4658..00000000
--- a/vendor/plugins/has_many_polymorphs/test/models/frog.rb
+++ /dev/null
@@ -1,4 +0,0 @@
-class Frog < ActiveRecord::Base
-
-end
-
diff --git a/vendor/plugins/has_many_polymorphs/test/models/kitten.rb b/vendor/plugins/has_many_polymorphs/test/models/kitten.rb
deleted file mode 100644
index 2a244c03..00000000
--- a/vendor/plugins/has_many_polymorphs/test/models/kitten.rb
+++ /dev/null
@@ -1,3 +0,0 @@
-class Kitten < Cat
-# has_many :eaters_parents, :dependent => true, :as => 'eater'
-end
\ No newline at end of file
diff --git a/vendor/plugins/has_many_polymorphs/test/models/parentship.rb b/vendor/plugins/has_many_polymorphs/test/models/parentship.rb
deleted file mode 100644
index e87b759b..00000000
--- a/vendor/plugins/has_many_polymorphs/test/models/parentship.rb
+++ /dev/null
@@ -1,4 +0,0 @@
-class Parentship < ActiveRecord::Base
- belongs_to :parent, :class_name => "Person", :foreign_key => "parent_id"
- belongs_to :kid, :polymorphic => true, :foreign_type => "child_type"
-end
diff --git a/vendor/plugins/has_many_polymorphs/test/models/person.rb b/vendor/plugins/has_many_polymorphs/test/models/person.rb
deleted file mode 100644
index 5d019829..00000000
--- a/vendor/plugins/has_many_polymorphs/test/models/person.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-require 'parentship'
-class Person < ActiveRecord::Base
- has_many_polymorphs :kids,
- :through => :parentships,
- :from => [:people],
- :as => :parent,
- :polymorphic_type_key => "child_type",
- :conditions => "people.age < 10"
-end
diff --git a/vendor/plugins/has_many_polymorphs/test/models/petfood.rb b/vendor/plugins/has_many_polymorphs/test/models/petfood.rb
deleted file mode 100644
index df420ea8..00000000
--- a/vendor/plugins/has_many_polymorphs/test/models/petfood.rb
+++ /dev/null
@@ -1,39 +0,0 @@
-# see http://dev.rubyonrails.org/ticket/5935
-require 'eaters_foodstuff'
-require 'petfood'
-require 'cat'
-module Aquatic; end
-require 'aquatic/fish'
-require 'dog'
-require 'wild_boar'
-require 'kitten'
-require 'tabby'
-require 'extension_module'
-require 'other_extension_module'
-
-class Petfood < ActiveRecord::Base
- set_primary_key 'the_petfood_primary_key'
- has_many_polymorphs :eaters,
- :from => [:dogs, :petfoods, :wild_boars, :kittens,
- :tabbies, :"aquatic/fish"],
-# :dependent => :destroy, :destroy is now the default
- :rename_individual_collections => true,
- :as => :foodstuff,
- :foreign_key => "foodstuff_id",
- :ignore_duplicates => false,
- :conditions => "NULL IS NULL",
- :order => "eaters_foodstuffs.updated_at ASC",
- :parent_order => "petfoods.the_petfood_primary_key DESC",
- :parent_conditions => "petfoods.name IS NULL OR petfoods.name != 'Snausages'",
- :extend => [ExtensionModule, OtherExtensionModule, proc {}],
- :join_extend => proc {
- def a_method
- :correct_join_result
- end
- },
- :parent_extend => proc {
- def a_method
- :correct_parent_proc_result
- end
- }
- end
diff --git a/vendor/plugins/has_many_polymorphs/test/models/tabby.rb b/vendor/plugins/has_many_polymorphs/test/models/tabby.rb
deleted file mode 100644
index 3cd0f994..00000000
--- a/vendor/plugins/has_many_polymorphs/test/models/tabby.rb
+++ /dev/null
@@ -1,2 +0,0 @@
-class Tabby < Cat
-end
\ No newline at end of file
diff --git a/vendor/plugins/has_many_polymorphs/test/models/wild_boar.rb b/vendor/plugins/has_many_polymorphs/test/models/wild_boar.rb
deleted file mode 100644
index 27d36a53..00000000
--- a/vendor/plugins/has_many_polymorphs/test/models/wild_boar.rb
+++ /dev/null
@@ -1,3 +0,0 @@
-class WildBoar < ActiveRecord::Base
-end
-
diff --git a/vendor/plugins/has_many_polymorphs/test/modules/extension_module.rb b/vendor/plugins/has_many_polymorphs/test/modules/extension_module.rb
deleted file mode 100644
index 7cb4eff4..00000000
--- a/vendor/plugins/has_many_polymorphs/test/modules/extension_module.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-
-module ExtensionModule
- def a_method
- :correct_module_result
- end
- def self.a_method
- :incorrect_module_result
- end
-end
diff --git a/vendor/plugins/has_many_polymorphs/test/modules/other_extension_module.rb b/vendor/plugins/has_many_polymorphs/test/modules/other_extension_module.rb
deleted file mode 100644
index 16313bd8..00000000
--- a/vendor/plugins/has_many_polymorphs/test/modules/other_extension_module.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-
-module OtherExtensionModule
- def another_method
- :correct_other_module_result
- end
- def self.another_method
- :incorrect_other_module_result
- end
-end
diff --git a/vendor/plugins/has_many_polymorphs/test/patches/symlinked_plugins_1.2.6.diff b/vendor/plugins/has_many_polymorphs/test/patches/symlinked_plugins_1.2.6.diff
deleted file mode 100644
index 99e0df3e..00000000
--- a/vendor/plugins/has_many_polymorphs/test/patches/symlinked_plugins_1.2.6.diff
+++ /dev/null
@@ -1,46 +0,0 @@
-Index: /trunk/railties/lib/rails_generator/lookup.rb
-===================================================================
---- /trunk/railties/lib/rails_generator/lookup.rb (revision 4310)
-+++ /trunk/railties/lib/rails_generator/lookup.rb (revision 6101)
-@@ -101,5 +101,5 @@
- sources << PathSource.new(:lib, "#{::RAILS_ROOT}/lib/generators")
- sources << PathSource.new(:vendor, "#{::RAILS_ROOT}/vendor/generators")
-- sources << PathSource.new(:plugins, "#{::RAILS_ROOT}/vendor/plugins/**/generators")
-+ sources << PathSource.new(:plugins, "#{::RAILS_ROOT}/vendor/plugins/*/**/generators")
- end
- sources << PathSource.new(:user, "#{Dir.user_home}/.rails/generators")
-Index: /trunk/railties/lib/tasks/rails.rb
-===================================================================
---- /trunk/railties/lib/tasks/rails.rb (revision 5469)
-+++ /trunk/railties/lib/tasks/rails.rb (revision 6101)
-@@ -6,3 +6,3 @@
- # Load any custom rakefile extensions
- Dir["#{RAILS_ROOT}/lib/tasks/**/*.rake"].sort.each { |ext| load ext }
--Dir["#{RAILS_ROOT}/vendor/plugins/**/tasks/**/*.rake"].sort.each { |ext| load ext }
-+Dir["#{RAILS_ROOT}/vendor/plugins/*/**/tasks/**/*.rake"].sort.each { |ext| load ext }
-Index: /trunk/railties/lib/tasks/testing.rake
-===================================================================
---- /trunk/railties/lib/tasks/testing.rake (revision 5263)
-+++ /trunk/railties/lib/tasks/testing.rake (revision 6101)
-@@ -109,9 +109,9 @@
- t.pattern = "vendor/plugins/#{ENV['PLUGIN']}/test/**/*_test.rb"
- else
-- t.pattern = 'vendor/plugins/**/test/**/*_test.rb'
-+ t.pattern = 'vendor/plugins/*/**/test/**/*_test.rb'
- end
-
- t.verbose = true
- end
-- Rake::Task['test:plugins'].comment = "Run the plugin tests in vendor/plugins/**/test (or specify with PLUGIN=name)"
-+ Rake::Task['test:plugins'].comment = "Run the plugin tests in vendor/plugins/*/**/test (or specify with PLUGIN=name)"
- end
-Index: /trunk/railties/CHANGELOG
-===================================================================
---- /trunk/railties/CHANGELOG (revision 6069)
-+++ /trunk/railties/CHANGELOG (revision 6101)
-@@ -1,3 +1,5 @@
- *SVN*
-+
-+* Plugins may be symlinked in vendor/plugins. #4245 [brandon, progrium@gmail.com]
-
- * Resource generator depends on the model generator rather than duplicating it. #7269 [bscofield]
diff --git a/vendor/plugins/has_many_polymorphs/test/schema.rb b/vendor/plugins/has_many_polymorphs/test/schema.rb
deleted file mode 100644
index 39d869dc..00000000
--- a/vendor/plugins/has_many_polymorphs/test/schema.rb
+++ /dev/null
@@ -1,87 +0,0 @@
-ActiveRecord::Schema.define(:version => 0) do
- create_table :petfoods, :force => true, :primary_key => :the_petfood_primary_key do |t|
- t.column :name, :string
- t.column :created_at, :datetime, :null => false
- t.column :updated_at, :datetime, :null => false
- end
-
- create_table :bow_wows, :force => true do |t|
- t.column :name, :string
- t.column :created_at, :datetime, :null => false
- t.column :updated_at, :datetime, :null => false
- end
-
- create_table :cats, :force => true do |t|
- t.column :name, :string
- t.column :cat_type, :string
- t.column :created_at, :datetime, :null => false
- t.column :updated_at, :datetime, :null => false
- end
-
- create_table :frogs, :force => true do |t|
- t.column :name, :string
- t.column :created_at, :datetime, :null => false
- t.column :updated_at, :datetime, :null => false
- end
-
- create_table :wild_boars, :force => true do |t|
- t.column :name, :string
- t.column :created_at, :datetime, :null => false
- t.column :updated_at, :datetime, :null => false
- end
-
- create_table :eaters_foodstuffs, :force => true do |t|
- t.column :foodstuff_id, :integer
- t.column :eater_id, :integer
- t.column :some_attribute, :integer, :default => 0
- t.column :eater_type, :string
- t.column :created_at, :datetime, :null => false
- t.column :updated_at, :datetime, :null => false
- end
-
- create_table :fish, :force => true do |t|
- t.column :name, :string
- t.column :speed, :integer
- t.column :created_at, :datetime, :null => false
- t.column :updated_at, :datetime, :null => false
- end
-
- create_table :whales, :force => true do |t|
- t.column :name, :string
- t.column :created_at, :datetime, :null => false
- t.column :updated_at, :datetime, :null => false
- end
-
- create_table :little_whale_pupils, :force => true do |t|
- t.column :whale_id, :integer
- t.column :aquatic_pupil_id, :integer
- t.column :aquatic_pupil_type, :string
- t.column :created_at, :datetime, :null => false
- t.column :updated_at, :datetime, :null => false
- end
-
- create_table :keep_your_enemies_close, :force => true do |t|
- t.column :enemy_id, :integer
- t.column :enemy_type, :string
- t.column :protector_id, :integer
- t.column :protector_type, :string
- t.column :created_at, :datetime, :null => false
- t.column :updated_at, :datetime, :null => false
- end
-
- create_table :parentships, :force => true do |t|
- t.column :parent_id, :integer
- t.column :child_type, :string
- t.column :kid_id, :integer
- t.column :created_at, :datetime, :null => false
- t.column :updated_at, :datetime, :null => false
- end
-
- create_table :people, :force => true do |t|
- t.column :name, :string
- t.column :age, :integer
- t.column :created_at, :datetime, :null => false
- t.column :updated_at, :datetime, :null => false
- end
-
-end
diff --git a/vendor/plugins/has_many_polymorphs/test/setup.rb b/vendor/plugins/has_many_polymorphs/test/setup.rb
deleted file mode 100644
index 52535798..00000000
--- a/vendor/plugins/has_many_polymorphs/test/setup.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-
-# Setup integration system for the integration suite
-
-Dir.chdir "#{File.dirname(__FILE__)}/integration/app/" do
- Dir.chdir "vendor/plugins" do
- system("rm has_many_polymorphs; ln -s ../../../../../ has_many_polymorphs")
- end
-
- system "rake db:drop --trace RAILS_GEM_VERSION=2.2.2 "
- system "rake db:create --trace RAILS_GEM_VERSION=2.2.2 "
- system "rake db:migrate --trace"
- system "rake db:fixtures:load --trace"
-end
-
diff --git a/vendor/plugins/has_many_polymorphs/test/test_helper.rb b/vendor/plugins/has_many_polymorphs/test/test_helper.rb
deleted file mode 100644
index 546cbec6..00000000
--- a/vendor/plugins/has_many_polymorphs/test/test_helper.rb
+++ /dev/null
@@ -1,52 +0,0 @@
-
-$VERBOSE = nil
-require 'rubygems'
-require 'rake' # echoe relies on Rake being present but doesn't require it itself
-require 'echoe'
-require 'test/unit'
-require 'multi_rails_init'
-#require 'ruby-debug' # uncomment if needed (for Ruby >= 1.9 use require 'debug' where needed)
-
-if defined? ENV['MULTIRAILS_RAILS_VERSION']
- ENV['RAILS_GEM_VERSION'] = ENV['MULTIRAILS_RAILS_VERSION']
-end
-
-Echoe.silence do
- HERE = File.expand_path(File.dirname(__FILE__))
- $LOAD_PATH << HERE
- # $LOAD_PATH << "#{HERE}/integration/app"
-end
-
-LOG = "#{HERE}/integration/app/log/development.log"
-
-### For unit tests
-
-require 'integration/app/config/environment'
-require 'test_help'
-
-ActiveSupport::Inflector.inflections {|i| i.irregular 'fish', 'fish' }
-
-$LOAD_PATH.unshift(ActiveSupport::TestCase.fixture_path = HERE + "/fixtures")
-$LOAD_PATH.unshift(HERE + "/models")
-$LOAD_PATH.unshift(HERE + "/modules")
-
-class ActiveSupport::TestCase
- self.use_transactional_fixtures = !(ActiveRecord::Base.connection.is_a? ActiveRecord::ConnectionAdapters::MysqlAdapter rescue false)
- self.use_instantiated_fixtures = false
-end
-
-Echoe.silence do
- load(HERE + "/schema.rb")
-end
-
-### For integration tests
-
-def truncate
- system("> #{LOG}")
-end
-
-def log
- File.open(LOG, 'r') do |f|
- f.read
- end
-end
diff --git a/vendor/plugins/has_many_polymorphs/test/unit/has_many_polymorphs_test.rb b/vendor/plugins/has_many_polymorphs/test/unit/has_many_polymorphs_test.rb
deleted file mode 100644
index d24a32e7..00000000
--- a/vendor/plugins/has_many_polymorphs/test/unit/has_many_polymorphs_test.rb
+++ /dev/null
@@ -1,713 +0,0 @@
-require File.dirname(__FILE__) + '/../test_helper'
-
-require 'dog'
-require 'wild_boar'
-require 'frog'
-require 'cat'
-require 'kitten'
-require 'aquatic/whale'
-require 'aquatic/fish'
-require 'aquatic/pupils_whale'
-require 'beautiful_fight_relationship'
-
-class PolymorphTest < ActiveSupport::TestCase
-
- set_fixture_class :bow_wows => Dog
- set_fixture_class :keep_your_enemies_close => BeautifulFightRelationship
- set_fixture_class :whales => Aquatic::Whale
- set_fixture_class :fish => Aquatic::Fish
- set_fixture_class :little_whale_pupils => Aquatic::PupilsWhale
-
- fixtures :cats, :bow_wows, :frogs, :wild_boars, :eaters_foodstuffs, :petfoods,
- :fish, :whales, :little_whale_pupils, :keep_your_enemies_close, :people
-
- def setup
- @association_error = ActiveRecord::Associations::PolymorphicError
- @kibbles = Petfood.find(1)
- @bits = Petfood.find(2)
- @shamu = Aquatic::Whale.find(1)
- @swimmy = Aquatic::Fish.find(1)
- @rover = Dog.find(1)
- @spot = Dog.find(2)
- @puma = WildBoar.find(1)
- @chloe = Kitten.find(1)
- @alice = Kitten.find(2)
- @toby = Tabby.find(3)
- @froggy = Frog.find(1)
-
- @join_count = EatersFoodstuff.count
- @kibbles_eaters_count = @kibbles.eaters.size
- @bits_eaters_count = @bits.eaters.size
-
- @double_join_count = BeautifulFightRelationship.count
- @alice_enemies_count = @alice.enemies.size
- end
-
- def test_all_relationship_validities
- # q = []
- # ObjectSpace.each_object(Class){|c| q << c if c.ancestors.include? ActiveRecord::Base }
- # q.each{|c| puts "#{c.name}.reflect_on_all_associations.map(&:check_validity!)"}
- Petfood.reflect_on_all_associations.map(&:check_validity!)
- Tabby.reflect_on_all_associations.map(&:check_validity!)
- Kitten.reflect_on_all_associations.map(&:check_validity!)
- Dog.reflect_on_all_associations.map(&:check_validity!)
- Canine.reflect_on_all_associations.map(&:check_validity!)
- Aquatic::Fish.reflect_on_all_associations.map(&:check_validity!)
- EatersFoodstuff.reflect_on_all_associations.map(&:check_validity!)
- WildBoar.reflect_on_all_associations.map(&:check_validity!)
- Frog.reflect_on_all_associations.map(&:check_validity!)
- Cat.reflect_on_all_associations.map(&:check_validity!)
- BeautifulFightRelationship.reflect_on_all_associations.map(&:check_validity!)
- Person.reflect_on_all_associations.map(&:check_validity!)
- Parentship.reflect_on_all_associations.map(&:check_validity!)
- Aquatic::Whale.reflect_on_all_associations.map(&:check_validity!)
- Aquatic::PupilsWhale.reflect_on_all_associations.map(&:check_validity!)
- end
-
- def test_assignment
- assert @kibbles.eaters.blank?
- assert @kibbles.eaters.push(Cat.find_by_name('Chloe'))
- assert_equal @kibbles_eaters_count += 1, @kibbles.eaters.count
-
- @kibbles.reload
- assert_equal @kibbles_eaters_count, @kibbles.eaters.count
- end
-
- def test_duplicate_assignment
- # try to add a duplicate item when :ignore_duplicates is false
- @kibbles.eaters.push(@alice)
- assert @kibbles.eaters.any? {|obj| obj == @alice}
- @kibbles.eaters.push(@alice)
- assert_equal @kibbles_eaters_count + 2, @kibbles.eaters.count
- assert_equal @join_count + 2, EatersFoodstuff.count
- end
-
- def test_create_and_push
- assert @kibbles.eaters.push(@spot)
- assert_equal @kibbles_eaters_count += 1, @kibbles.eaters.count
- assert @kibbles.eaters << @rover
- assert @kibbles.eaters << Kitten.create(:name => "Miranda")
- assert_equal @kibbles_eaters_count += 2, @kibbles.eaters.length
-
- @kibbles.reload
- assert_equal @kibbles_eaters_count, @kibbles.eaters.length
-
- # test that ids and new flags were set appropriately
- assert_not_nil @kibbles.eaters[0].id
- assert !@kibbles.eaters[1].new_record?
- end
-
- def test_reload
- assert @kibbles.reload
- assert @kibbles.eaters.reload
- end
-
- def test_add_join_record
- assert_equal Kitten, @chloe.class
- assert join = EatersFoodstuff.new(:foodstuff_id => @bits.id, :eater_id => @chloe.id, :eater_type => @chloe.class.name )
- assert join.save!
- assert join.id
- assert_equal @join_count + 1, EatersFoodstuff.count
-
- #assert_equal @bits_eaters_count, @bits.eaters.size # Doesn't behave this way on latest edge anymore
- assert_equal @bits_eaters_count + 1, @bits.eaters.count # SQL
-
- # reload; is the new association there?
- assert @bits.eaters.reload
- assert @bits.eaters.any? {|obj| obj == @chloe}
- end
-
- def test_build_join_record_on_association
- assert_equal Kitten, @chloe.class
- assert join = @chloe.eaters_foodstuffs.build(:foodstuff => @bits)
- # assert_equal join.eater_type, @chloe.class.name # will be STI parent type
- assert join.save!
- assert join.id
- assert_equal @join_count + 1, EatersFoodstuff.count
-
- assert @bits.eaters.reload
- assert @bits.eaters.any? {|obj| obj == @chloe}
- end
-
-# not supporting this, since has_many :through doesn't support it either
-# def test_add_unsaved
-# # add an unsaved item
-# assert @bits.eaters << Kitten.new(:name => "Bridget")
-# assert_nil Kitten.find_by_name("Bridget")
-# assert_equal @bits_eaters_count + 1, @bits.eaters.count
-#
-# assert @bits.save
-# @bits.reload
-# assert_equal @bits_eaters_count + 1, @bits.eaters.count
-#
-# end
-
- def test_self_reference
- assert @kibbles.eaters << @bits
- assert_equal @kibbles_eaters_count += 1, @kibbles.eaters.count
- assert @kibbles.eaters.any? {|obj| obj == @bits}
- @kibbles.reload
- assert @kibbles.foodstuffs_of_eaters.blank?
-
- @bits.reload
- assert @bits.foodstuffs_of_eaters.any? {|obj| obj == @kibbles}
- assert_equal [@kibbles], @bits.foodstuffs_of_eaters
- end
-
- def test_remove
- assert @kibbles.eaters << @chloe
- @kibbles.reload
- assert @kibbles.eaters.delete(@kibbles.eaters[0])
- assert_equal @kibbles_eaters_count, @kibbles.eaters.count
- end
-
- def test_destroy
- assert @kibbles.eaters.push(@chloe)
- @kibbles.reload
- assert @kibbles.eaters.length > 0
- assert @kibbles.eaters[0].destroy
- @kibbles.reload
- assert_equal @kibbles_eaters_count, @kibbles.eaters.count
- end
-
- def test_clear
- @kibbles.eaters << [@chloe, @spot, @rover]
- @kibbles.reload
- assert @kibbles.eaters.clear.blank?
- assert @kibbles.eaters.blank?
- @kibbles.reload
- assert @kibbles.eaters.blank?
- end
-
- def test_individual_collections
- assert @kibbles.eaters.push(@chloe)
- # check if individual collections work
- assert_equal @kibbles.eater_kittens.length, 1
- assert @kibbles.eater_dogs
- assert 1, @rover.eaters_foodstuffs.count
- end
-
- def test_individual_collections_push
- assert_equal [@chloe], (@kibbles.eater_kittens << @chloe)
- @kibbles.reload
- assert @kibbles.eaters.any? {|obj| obj == @chloe}
- assert @kibbles.eater_kittens.any? {|obj| obj == @chloe}
- assert !@kibbles.eater_dogs.any? {|obj| obj == @chloe}
- end
-
- def test_individual_collections_delete
- @kibbles.eaters << [@chloe, @spot, @rover]
- @kibbles.reload
- assert_equal [@chloe], @kibbles.eater_kittens.delete(@chloe)
- assert @kibbles.eater_kittens.empty?
- @kibbles.eater_kittens.delete(@chloe) # what should this return?
-
- @kibbles.reload
- assert @kibbles.eater_kittens.empty?
- assert @kibbles.eater_dogs.any? {|obj| obj == @spot}
- end
-
- def test_individual_collections_clear
- @kibbles.eaters << [@chloe, @spot, @rover]
- @kibbles.reload
-
- assert_equal [], @kibbles.eater_kittens.clear
- assert @kibbles.eater_kittens.empty?
- assert_equal 2, @kibbles.eaters.size
-
- assert @kibbles.eater_kittens.empty?
- assert_equal 2, @kibbles.eaters.size
- assert !@kibbles.eater_kittens.any? {|obj| obj == @chloe}
- assert !@kibbles.eaters.any? {|obj| obj == @chloe}
-
- @kibbles.reload
- assert @kibbles.eater_kittens.empty?
- assert_equal 2, @kibbles.eaters.size
- assert !@kibbles.eater_kittens.any? {|obj| obj == @chloe}
- assert !@kibbles.eaters.any? {|obj| obj == @chloe}
- end
-
- def test_childrens_individual_collections
- assert Cat.find_by_name('Chloe').eaters_foodstuffs
- assert @kibbles.eaters_foodstuffs
- end
-
- def test_self_referential_join_tables
- # check that the self-reference join tables go the right ways
- assert_equal @kibbles_eaters_count, @kibbles.eaters_foodstuffs.count
- assert_equal @kibbles.eaters_foodstuffs.count, @kibbles.eaters_foodstuffs_as_child.count
- end
-
- def test_dependent
- assert @kibbles.eaters << @chloe
- @kibbles.reload
-
- # delete ourself and see if :dependent was obeyed
- dependent_rows = @kibbles.eaters_foodstuffs
- assert_equal dependent_rows.length, @kibbles.eaters.count
- @join_count = EatersFoodstuff.count
-
- @kibbles.destroy
- assert_equal @join_count - dependent_rows.length, EatersFoodstuff.count
- assert_equal 0, EatersFoodstuff.find(:all, :conditions => ['foodstuff_id = ?', 1] ).length
- end
-
- def test_normal_callbacks
- assert @rover.respond_to?(:after_initialize)
- assert @rover.respond_to?(:after_find)
- assert @rover.after_initialize_test
- assert @rover.after_find_test
- end
-
- def test_model_callbacks_not_overridden_by_plugin_callbacks
- assert 0, @bits.eaters.count
- assert @bits.eaters.push(@rover)
- @bits.save
- @bits2 = Petfood.find_by_name("Bits")
- @bits.reload
- assert rover = @bits2.eaters.select { |x| x.name == "Rover" }[0]
- assert rover.after_initialize_test
- assert rover.after_find_test
- end
-
- def test_number_of_join_records
- assert EatersFoodstuff.create(:foodstuff_id => 1, :eater_id => 1, :eater_type => "Cat")
- @join_count = EatersFoodstuff.count
- assert @join_count > 0
- end
-
- def test_number_of_regular_records
- dogs = Dog.count
- assert Dog.new(:name => "Auggie").save!
- assert dogs + 1, Dog.count
- end
-
- def test_attributes_come_through_when_child_has_underscore_in_table_name
- join = EatersFoodstuff.new(:foodstuff_id => @bits.id, :eater_id => @puma.id, :eater_type => @puma.class.name)
- join.save!
-
- @bits.eaters.reload
-
- assert_equal "Puma", @puma.name
- assert_equal "Puma", @bits.eaters.first.name
- end
-
-
- def test_before_save_on_join_table_is_not_clobbered_by_sti_base_class_fix
- assert @kibbles.eaters << @chloe
- assert_equal 3, @kibbles.eaters_foodstuffs.first.some_attribute
- end
-
- def test_sti_type_counts_are_correct
- @kibbles.eaters << [@chloe, @alice, @toby]
- assert_equal 2, @kibbles.eater_kittens.count
- assert_equal 1, @kibbles.eater_tabbies.count
- assert !@kibbles.respond_to?(:eater_cats)
- end
-
-
- def test_creating_namespaced_relationship
- assert @shamu.aquatic_pupils.empty?
- @shamu.aquatic_pupils << @swimmy
- assert_equal 1, @shamu.aquatic_pupils.length
- @shamu.reload
- assert_equal 1, @shamu.aquatic_pupils.length
- end
-
- def test_namespaced_polymorphic_collection
- @shamu.aquatic_pupils << @swimmy
- assert @shamu.aquatic_pupils.any? {|obj| obj == @swimmy}
- @shamu.reload
- assert @shamu.aquatic_pupils.any? {|obj| obj == @swimmy}
-
- @shamu.aquatic_pupils << @spot
- assert @shamu.dogs.any? {|obj| obj == @spot}
- assert @shamu.aquatic_pupils.any? {|obj| obj == @swimmy}
- assert_equal @swimmy, @shamu.aquatic_fish.first
- assert_equal 10, @shamu.aquatic_fish.first.speed
- end
-
- def test_deleting_namespaced_relationship
- @shamu.aquatic_pupils << @swimmy
- @shamu.aquatic_pupils << @spot
-
- @shamu.reload
- @shamu.aquatic_pupils.delete @spot
- assert !@shamu.dogs.any? {|obj| obj == @spot}
- assert !@shamu.aquatic_pupils.any? {|obj| obj == @spot}
- assert_equal 1, @shamu.aquatic_pupils.length
- end
-
- def test_unrenamed_parent_of_namespaced_child
- @shamu.aquatic_pupils << @swimmy
- assert_equal [@shamu], @swimmy.whales
- end
-
- def test_empty_double_collections
- assert @puma.enemies.empty?
- assert @froggy.protectors.empty?
- assert @alice.enemies.empty?
- assert @spot.protectors.empty?
- assert @alice.beautiful_fight_relationships_as_enemy.empty?
- assert @alice.beautiful_fight_relationships_as_protector.empty?
- assert @alice.beautiful_fight_relationships.empty?
- end
-
- def test_double_collection_assignment
- @alice.enemies << @spot
- @alice.reload
- @spot.reload
- assert @spot.protectors.any? {|obj| obj == @alice}
- assert @alice.enemies.any? {|obj| obj == @spot}
- assert !@alice.protectors.any? {|obj| obj == @alice}
- assert_equal 1, @alice.beautiful_fight_relationships_as_protector.size
- assert_equal 0, @alice.beautiful_fight_relationships_as_enemy.size
- assert_equal 1, @alice.beautiful_fight_relationships.size
-
- # self reference
- assert_equal 1, @alice.enemies.length
- @alice.enemies.push @alice
- assert @alice.enemies.any? {|obj| obj == @alice}
- assert_equal 2, @alice.enemies.length
- @alice.reload
- assert_equal 2, @alice.beautiful_fight_relationships_as_protector.size
- assert_equal 1, @alice.beautiful_fight_relationships_as_enemy.size
- assert_equal 3, @alice.beautiful_fight_relationships.size
- end
-
- def test_double_collection_build_join_record_on_association
-
- join = @alice.beautiful_fight_relationships_as_protector.build(:enemy => @spot)
-
- assert_equal @alice.class.base_class.name, join.protector_type
- assert_nothing_raised { join.save! }
-
- assert join.id
- assert_equal @double_join_count + 1, BeautifulFightRelationship.count
-
- assert @alice.enemies.reload
- assert @alice.enemies.any? {|obj| obj == @spot}
- end
-
- def test_double_dependency_injection
-# breakpoint
- end
-
- def test_double_collection_deletion
- @alice.enemies << @spot
- @alice.reload
- assert @alice.enemies.any? {|obj| obj == @spot}
- @alice.enemies.delete(@spot)
- assert !@alice.enemies.any? {|obj| obj == @spot}
- assert @alice.enemies.empty?
- @alice.reload
- assert !@alice.enemies.any? {|obj| obj == @spot}
- assert @alice.enemies.empty?
- assert_equal 0, @alice.beautiful_fight_relationships.size
- end
-
- def test_double_collection_deletion_from_opposite_side
- @alice.protectors << @puma
- @alice.reload
- assert @alice.protectors.any? {|obj| obj == @puma}
- @alice.protectors.delete(@puma)
- assert !@alice.protectors.any? {|obj| obj == @puma}
- assert @alice.protectors.empty?
- @alice.reload
- assert !@alice.protectors.any? {|obj| obj == @puma}
- assert @alice.protectors.empty?
- assert_equal 0, @alice.beautiful_fight_relationships.size
- end
-
- def test_individual_collections_created_for_double_relationship
- assert @alice.dogs.empty?
- @alice.enemies << @spot
-
- assert @alice.enemies.any? {|obj| obj == @spot}
- assert !@alice.kittens.any? {|obj| obj == @alice}
-
- assert !@alice.dogs.any? {|obj| obj == @spot}
- @alice.reload
- assert @alice.dogs.any? {|obj| obj == @spot}
- assert !WildBoar.find(@alice.id).dogs.any? {|obj| obj == @spot} # make sure the parent type is checked
- end
-
- def test_individual_collections_created_for_double_relationship_from_opposite_side
- assert @alice.wild_boars.empty?
- @alice.protectors << @puma
- @alice.reload
-
- assert @alice.protectors.any? {|obj| obj == @puma}
- assert @alice.wild_boars.any? {|obj| obj == @puma}
-
- assert !Dog.find(@alice.id).wild_boars.any? {|obj| obj == @puma} # make sure the parent type is checked
- end
-
- def test_self_referential_individual_collections_created_for_double_relationship
- @alice.enemies << @alice
- @alice.reload
- assert @alice.enemy_kittens.any? {|obj| obj == @alice}
- assert @alice.protector_kittens.any? {|obj| obj == @alice}
- assert @alice.kittens.any? {|obj| obj == @alice}
- assert_equal 2, @alice.kittens.size
-
- @alice.enemies << (@chloe = Kitten.find_by_name('Chloe'))
- @alice.reload
- assert @alice.enemy_kittens.any? {|obj| obj == @chloe}
- assert !@alice.protector_kittens.any? {|obj| obj == @chloe}
- assert @alice.kittens.any? {|obj| obj == @chloe}
- assert_equal 3, @alice.kittens.size
- end
-
- def test_child_of_polymorphic_join_can_reach_parent
- @alice.enemies << @spot
- @alice.reload
- assert @spot.protectors.any? {|obj| obj == @alice}
- end
-
- def test_double_collection_deletion_from_child_polymorphic_join
- @alice.enemies << @spot
- @spot.protectors.delete(@alice)
- assert !@spot.protectors.any? {|obj| obj == @alice}
- @alice.reload
- assert !@alice.enemies.any? {|obj| obj == @spot}
- BeautifulFightRelationship.create(:protector_id => 2, :protector_type => "Dog", :enemy_id => @spot.id, :enemy_type => @spot.class.name)
- @alice.enemies << @spot
- @spot.protectors.delete(@alice)
- assert !@spot.protectors.any? {|obj| obj == @alice}
- end
-
- def test_collection_query_on_unsaved_record
- assert Dog.new.enemies.empty?
- assert Dog.new.foodstuffs_of_eaters.empty?
- end
-
- def test_double_individual_collections_push
- assert_equal [@chloe], (@spot.protector_kittens << @chloe)
- @spot.reload
- assert @spot.protectors.any? {|obj| obj == @chloe}
- assert @spot.protector_kittens.any? {|obj| obj == @chloe}
- assert !@spot.protector_dogs.any? {|obj| obj == @chloe}
-
- assert_equal [@froggy], (@spot.frogs << @froggy)
- @spot.reload
- assert @spot.enemies.any? {|obj| obj == @froggy}
- assert @spot.frogs.any? {|obj| obj == @froggy}
- assert !@spot.enemy_dogs.any? {|obj| obj == @froggy}
- end
-
- def test_double_individual_collections_delete
- @spot.protectors << [@chloe, @puma]
- @spot.reload
- assert_equal [@chloe], @spot.protector_kittens.delete(@chloe)
- assert @spot.protector_kittens.empty?
- @spot.protector_kittens.delete(@chloe) # again, unclear what .delete should return
-
- @spot.reload
- assert @spot.protector_kittens.empty?
- assert @spot.wild_boars.any? {|obj| obj == @puma}
- end
-
- def test_double_individual_collections_clear
- @spot.protectors << [@chloe, @puma, @alice]
- @spot.reload
- assert_equal [], @spot.protector_kittens.clear
- assert @spot.protector_kittens.empty?
- assert_equal 1, @spot.protectors.size
- @spot.reload
- assert @spot.protector_kittens.empty?
- assert_equal 1, @spot.protectors.size
- assert !@spot.protector_kittens.any? {|obj| obj == @chloe}
- assert !@spot.protectors.any? {|obj| obj == @chloe}
- assert !@spot.protector_kittens.any? {|obj| obj == @alice}
- assert !@spot.protectors.any? {|obj| obj == @alice}
- assert @spot.protectors.any? {|obj| obj == @puma}
- assert @spot.wild_boars.any? {|obj| obj == @puma}
- end
-
- def test_single_extensions
- assert_equal :correct_block_result, @shamu.aquatic_pupils.a_method
- @kibbles.eaters.push(@alice)
- @kibbles.eaters.push(@spot)
- assert_equal :correct_join_result, @kibbles.eaters_foodstuffs.a_method
- assert_equal :correct_module_result, @kibbles.eaters.a_method
- assert_equal :correct_other_module_result, @kibbles.eaters.another_method
- @kibbles.eaters.each do |eater|
- assert_equal :correct_join_result, eater.eaters_foodstuffs.a_method
- end
- assert_equal :correct_parent_proc_result, @kibbles.foodstuffs_of_eaters.a_method
- assert_equal :correct_parent_proc_result, @kibbles.eaters.first.foodstuffs_of_eaters.a_method
- end
-
- def test_double_extensions
- assert_equal :correct_proc_result, @spot.protectors.a_method
- assert_equal :correct_module_result, @spot.enemies.a_method
- assert_equal :correct_join_result, @spot.beautiful_fight_relationships_as_enemy.a_method
- assert_equal :correct_join_result, @spot.beautiful_fight_relationships_as_protector.a_method
- assert_equal :correct_join_result, @froggy.beautiful_fight_relationships.a_method
- assert_equal :correct_join_result, @froggy.beautiful_fight_relationships_as_enemy.a_method
- assert_raises(NoMethodError) {@froggy.beautiful_fight_relationships_as_protector.a_method}
- end
-
- def test_pluralization_checks
- assert_raises(@association_error) {
- eval "class SomeModel < ActiveRecord::Base
- has_many_polymorphs :polymorphs, :from => [:dog, :cats]
- end" }
- assert_raises(@association_error) {
- eval "class SomeModel < ActiveRecord::Base
- has_many_polymorphs :polymorph, :from => [:dogs, :cats]
- end" }
- assert_raises(@association_error) {
- eval "class SomeModel < ActiveRecord::Base
- acts_as_double_polymorphic_join :polymorph => [:dogs, :cats], :unimorphs => [:dogs, :cats]
- end" }
- end
-
- def test_error_message_on_namespaced_targets
- assert_raises(@association_error) {
- eval "class SomeModel < ActiveRecord::Base
- has_many_polymorphs :polymorphs, :from => [:fish]
- end" }
- end
-
- def test_single_custom_finders
- [@kibbles, @alice, @puma, @spot, @bits].each {|record| @kibbles.eaters << record; sleep 1} # XXX yeah i know
- assert_equal @kibbles.eaters, @kibbles.eaters.find(:all, :order => "eaters_foodstuffs.created_at ASC")
- assert_equal @kibbles.eaters.reverse, @kibbles.eaters.find(:all, :order => "eaters_foodstuffs.created_at DESC")
- if (ActiveRecord::Base.connection.is_a? ActiveRecord::ConnectionAdapters::MysqlAdapter rescue false)
- assert_equal @kibbles.eaters.sort_by(&:created_at), @kibbles.eaters.find(:all, :order => "IFNULL(bow_wows.created_at,(IFNULL(petfoods.created_at,(IFNULL(wild_boars.created_at,(IFNULL(cats.created_at,fish.created_at))))))) ASC")
- end
- assert_equal @kibbles.eaters.select{|x| x.is_a? Petfood}, @kibbles.eater_petfoods.find(:all, :order => "eaters_foodstuffs.created_at ASC")
- end
-
- def test_double_custom_finders
- @spot.protectors << [@chloe, @puma, @alice]
- assert_equal [@chloe], @spot.protectors.find(:all, :conditions => ["cats.name = ?", @chloe.name], :limit => 1)
- assert_equal [], @spot.protectors.find(:all, :conditions => ["cats.name = ?", @chloe.name], :limit => 1, :offset => 1)
- assert_equal 2, @spot.protectors.find(:all, :limit => 100, :offset => 1).size
- end
-
- def test_single_custom_finder_parameters_carry_to_individual_relationships
- # XXX test nullout here
- end
-
- def test_double_custom_finder_parameters_carry_to_individual_relationships
- # XXX test nullout here
- end
-
- def test_include_doesnt_fail
- assert_nothing_raised do
- @spot.protectors.find(:all, :include => :wild_boars)
- end
- end
-
- def test_abstract_method
- assert_equal :correct_abstract_method_response, @spot.an_abstract_method
- end
-
- def test_missing_target_should_raise
- @kibbles.eaters << [@kibbles, @alice, @puma, @spot, @bits]
- @spot.destroy_without_callbacks
- assert_raises(@association_error) { @kibbles.eaters.reload }
-# assert_raises(@association_error) { @kibbles.eater_dogs.reload } # bah AR
- end
-
- def test_lazy_loading_is_lazy
- # XXX
- end
-
- def test_push_with_skip_duplicates_false_doesnt_load_target
- # Loading kibbles locally again because setup calls .size which loads target
- kibbles = Petfood.find(1)
- assert !kibbles.eaters.loaded?
- assert !(kibbles.eater_dogs << Dog.create!(:name => "Mongy")).loaded?
- assert !kibbles.eaters.loaded?
- end
-
- def test_association_foreign_key_is_sane
- assert_equal "eater_id", Petfood.reflect_on_association(:eaters).association_foreign_key
- end
-
- def test_reflection_instance_methods_are_sane
- assert_equal EatersFoodstuff, Petfood.reflect_on_association(:eaters).klass
- assert_equal EatersFoodstuff.name, Petfood.reflect_on_association(:eaters).class_name
- end
-
- def test_parent_order
- @alice.foodstuffs_of_eaters << Petfood.find(:all, :order => "the_petfood_primary_key ASC")
- @alice.reload #not necessary
- assert_equal [2,1], @alice.foodstuffs_of_eaters.map(&:id)
- end
-
- def test_parent_conditions
- @kibbles.eaters << @alice
- assert_equal [@alice], @kibbles.eaters
-
- @snausages = Petfood.create(:name => 'Snausages')
- @snausages.eaters << @alice
- assert_equal [@alice], @snausages.eaters
-
- assert_equal [@kibbles], @alice.foodstuffs_of_eaters
- end
-
- def test_self_referential_hmp_with_conditions
- p = Person.find(:first)
- kid = Person.create(:name => "Tim", :age => 3)
- p.kids << kid
-
- kid.reload; p.reload
-
- # assert_equal [p], kid.parents
- # assert Rails.has_one? Bug
- # non-standard foreign_type key is not set properly when you are the polymorphic interface of a has_many going to a :through
-
- assert_equal [kid], p.kids
- assert_equal [kid], p.people
- end
-
-# def test_polymorphic_include
-# @kibbles.eaters << [@kibbles, @alice, @puma, @spot, @bits]
-# assert @kibbles.eaters.include?(@kibbles.eaters_foodstuffs.find(:all, :include => :eater).first.eater)
-# end
-#
-# def test_double_polymorphic_include
-# end
-#
-# def test_single_child_include
-# end
-#
-# def test_double_child_include
-# end
-#
-# def test_single_include_from_parent
-# end
-#
-# def test_double_include_from_parent
-# end
-#
-# def test_meta_referential_single_include
-# end
-#
-# def test_meta_referential_double_include
-# end
-#
-# def test_meta_referential_single_include
-# end
-#
-# def test_meta_referential_single_double_multi_include
-# end
-#
-# def test_dont_ignore_duplicates
-# end
-#
-# def test_ignore_duplicates
-# end
-#
-# def test_tagging_system_generator
-# end
-#
-# def test_tagging_system_library
-# end
-
-end
diff --git a/vendor/plugins/jrails/.gitignore b/vendor/plugins/jrails/.gitignore
deleted file mode 100644
index 088af208..00000000
--- a/vendor/plugins/jrails/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-pkg/*
diff --git a/vendor/plugins/jrails/CHANGELOG b/vendor/plugins/jrails/CHANGELOG
deleted file mode 100644
index 5e6a83c2..00000000
--- a/vendor/plugins/jrails/CHANGELOG
+++ /dev/null
@@ -1,43 +0,0 @@
-0.5.0 (31 July 2009)
-* Gemification
-* Support for Ruby 1.9.X
-* Updated to jQuery 1.3.2
-* Updated to jQuery UI 1.7.2
-* Created a jrails binary (runs rake tasks) because rails does not (yet?) pickup
-tasks from gem plugins
-* Changed default to use jQuery compatibility name (not $)
-* Created a scrub task that will remove the prototype / script.aculo.us
-javascript files
-* better approximate scriptaculous effect names
-* add support for page[:element_id].visual_effect(:effect) as well as page.visual_effect(:effect, :element_id)
-* added a reset form function to jrails.js (stolen from jquery form)
-* can now use jquery selectors in all functions
-* added javascript_function helper to render inline rjs helpers
-* better support for sortable_element
-
-0.4.0 (16 June 2008)
-* updated to jquery-ui 1.5 & merged js into single file
-* Added jQuery.noConflict support
-* support for value/val
-* additional support for update/delete methods
-* support for success/failure hash
-* setRequestHeader now gets called globally
-* Better support for droppables, sortables
-* Add support for prototype AJAX callbacks
-* better support for AJAX form calls
-
-0.3.0 (22 Feb 2008)
-* updated to jquery-fx 1.0b and jquery-ui 1.5b
-* Add text/javascript request header to fix format.js
-* Added Tasks (thanks ggarside)
-* Improve visual_effects methods
-* Fixed some RJS calls
-* Fixed observer code for ie
-
-0.2.0 (26 Nov 2007)
-* Vastly Improved FX
-* Improved Form Observers
-* Fixed Rails <= 1.2.6 Compatibility
-
-0.1.0 (15 Nov 2007)
-* Initial release
diff --git a/vendor/plugins/jrails/LICENSE b/vendor/plugins/jrails/LICENSE
deleted file mode 100644
index 66afde43..00000000
--- a/vendor/plugins/jrails/LICENSE
+++ /dev/null
@@ -1,18 +0,0 @@
-Copyright (c) 2008 Aaron Eisenberger
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/vendor/plugins/jrails/README.rdoc b/vendor/plugins/jrails/README.rdoc
deleted file mode 100644
index 0519f92e..00000000
--- a/vendor/plugins/jrails/README.rdoc
+++ /dev/null
@@ -1,21 +0,0 @@
-= jRails
-
-jRails is a drop-in jQuery replacement for the Rails Prototype/script.aculo.us helpers.
-
-== Resources
-
-Install
-
-* .script/plugin install git://github.com/aaronchi/jrails.git
-
-Project Site
-
-* http://code.google.com/p/ennerchi
-
-Web Site
-
-* http://www.ennerchi.com/projects/jrails
-
-Group Site
-
-* http://groups.google.com/group/jrails
diff --git a/vendor/plugins/jrails/Rakefile b/vendor/plugins/jrails/Rakefile
deleted file mode 100644
index ab336c2f..00000000
--- a/vendor/plugins/jrails/Rakefile
+++ /dev/null
@@ -1,18 +0,0 @@
-require 'rubygems'
-require 'rake'
-
-begin
- require 'jeweler'
- Jeweler::Tasks.new do |gem|
- gem.name = "jrails"
- gem.summary = "jRails is a drop-in jQuery replacement for the Rails Prototype/script.aculo.us helpers."
- gem.description = "Using jRails, you can get all of the same default Rails helpers for javascript functionality using the lighter jQuery library."
- gem.email = "aaronchi@gmail.com"
- gem.homepage = "http://ennerchi.com/projects/jrails"
- gem.authors = ["Aaron Eisenberger", "Patrick Hurley"]
- gem.rubyforge_project = "jrails"
- gem.files = FileList["[A-Z]*.rb","{bin,javascripts,lib,rails,tasks}/**/*"]
- end
-rescue LoadError
- puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
-end
\ No newline at end of file
diff --git a/vendor/plugins/jrails/VERSION.yml b/vendor/plugins/jrails/VERSION.yml
deleted file mode 100644
index 61a5e390..00000000
--- a/vendor/plugins/jrails/VERSION.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-:patch: 1
-:major: 0
-:minor: 5
\ No newline at end of file
diff --git a/vendor/plugins/jrails/bin/jrails b/vendor/plugins/jrails/bin/jrails
deleted file mode 100755
index 8bfd07bf..00000000
--- a/vendor/plugins/jrails/bin/jrails
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/usr/bin/env ruby
-
-require 'rubygems'
-require 'rake'
-
-RAILS_ROOT = Dir.pwd
-rakeapp = Rake.application
-fname =File.join(File.dirname(__FILE__), '..', 'tasks', 'jrails.rake')
-load fname
-
-task :help do
- puts "jrails [command]\n\n"
- rakeapp.options.show_task_pattern = Regexp.new('^[hius]')
- rakeapp.display_tasks_and_comments
-end
-
-desc 'Installs the jQuery and jRails javascripts to public/javascripts'
-task :install do
- Rake::Task['jrails:js:install'].invoke
-end
-
-desc 'Remove the prototype / script.aculo.us javascript files'
-task :scrub do
- Rake::Task['jrails:js:scrub'].invoke
-end
-
-rakeapp.init("jrails")
-task :default => [:help]
-
-rakeapp.top_level
diff --git a/vendor/plugins/jrails/init.rb b/vendor/plugins/jrails/init.rb
deleted file mode 100644
index ca9c82a9..00000000
--- a/vendor/plugins/jrails/init.rb
+++ /dev/null
@@ -1 +0,0 @@
-require 'rails/init.rb'
diff --git a/vendor/plugins/jrails/install.rb b/vendor/plugins/jrails/install.rb
deleted file mode 100644
index d8f6e9bf..00000000
--- a/vendor/plugins/jrails/install.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# Install hook code here
-puts "Copying files..."
-dir = "javascripts"
-["jquery-ui.js", "jquery.js", "jrails.js"].each do |js_file|
- dest_file = File.join(RAILS_ROOT, "public", dir, js_file)
- src_file = File.join(File.dirname(__FILE__) , dir, js_file)
- FileUtils.cp_r(src_file, dest_file)
-end
-puts "Files copied - Installation complete!"
diff --git a/vendor/plugins/jrails/javascripts/jquery-ui.js b/vendor/plugins/jrails/javascripts/jquery-ui.js
deleted file mode 100644
index 3efce203..00000000
--- a/vendor/plugins/jrails/javascripts/jquery-ui.js
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * jQuery UI 1.7.2
- *
- * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT (MIT-LICENSE.txt)
- * and GPL (GPL-LICENSE.txt) licenses.
- *
- * http://docs.jquery.com/UI
- */
-jQuery.ui||(function(c){var i=c.fn.remove,d=c.browser.mozilla&&(parseFloat(c.browser.version)<1.9);c.ui={version:"1.7.2",plugin:{add:function(k,l,n){var m=c.ui[k].prototype;for(var j in n){m.plugins[j]=m.plugins[j]||[];m.plugins[j].push([l,n[j]])}},call:function(j,l,k){var n=j.plugins[l];if(!n||!j.element[0].parentNode){return}for(var m=0;m
k))&&((e>=g&&e<=c)||(d>=g&&d<=c)||(e
+ <%= submit_tag "Save Translations" %> +
+ <% @paginated_keys.each do |key| + from_text = lookup(@from_locale, key) + to_text = lookup(@to_locale, key) + line_size = 100 + n_lines = n_lines(from_text, line_size) + field_name = "key[#{key}]" + %> ++ <%= simple_format(h(from_text)) %> +
+ <% end %> ++ <% if n_lines > 1 %> + <%= text_area_tag(field_name, to_text, :size => "#{line_size}x#{n_lines}", :id => key) %> + <% else %> + <%= text_field_tag(field_name, to_text, :size => line_size, :id => key) %> + <% end %> +
+
+
+ <%= link_to_function 'Auto Translate', "getGoogleTranslation('#{key}', \"#{escape_javascript(from_text)}\", '#{@from_locale}', '#{@to_locale}')", :style => 'padding: 0; margin: 0;' %>
+
+ Key:<%=h key %>
+ <% if @files[key] %>
+ File:<%= @files[key].join("
") %>
+ <% end %>
+
+
+ <%= submit_tag "Save Translations" %> +
+Now let's render us some pagination!
- <%= will_paginate @posts %> - -More detailed documentation: - -* WillPaginate::Finder::ClassMethods for pagination on your models; -* WillPaginate::ViewHelpers for your views. - - -== Authors and credits - -Authors:: Mislav Marohnić, PJ Hyett -Original announcement:: http://errtheblog.com/post/929 -Original PHP source:: http://www.strangerstudios.com/sandbox/pagination/diggstyle.php - -All these people helped making will_paginate what it is now with their code -contributions or just simply awesome ideas: - -Chris Wanstrath, Dr. Nic Williams, K. Adam Christensen, Mike Garey, Bence -Golda, Matt Aimonetti, Charles Brian Quinn, Desi McAdam, James Coglan, Matijs -van Zuijlen, Maria, Brendan Ribera, Todd Willey, Bryan Helmkamp, Jan Berkel, -Lourens Naudé, Rick Olson, Russell Norris, Piotr Usewicz, Chris Eppstein. - - -== Usable pagination in the UI - -There are some CSS styles to get you started in the "examples/" directory. They -are showcased in the "examples/index.html" file. - -More reading about pagination as design pattern: - -* Pagination 101: - http://kurafire.net/log/archive/2007/06/22/pagination-101 -* Pagination gallery: - http://www.smashingmagazine.com/2007/11/16/pagination-gallery-examples-and-good-practices/ -* Pagination on Yahoo Design Pattern Library: - http://developer.yahoo.com/ypatterns/parent.php?pattern=pagination - -Want to discuss, request features, ask questions? Join the -{Google group}[http://groups.google.com/group/will_paginate]. - diff --git a/vendor/plugins/will_paginate/Rakefile b/vendor/plugins/will_paginate/Rakefile deleted file mode 100644 index c3cf1c61..00000000 --- a/vendor/plugins/will_paginate/Rakefile +++ /dev/null @@ -1,62 +0,0 @@ -require 'rubygems' -begin - hanna_dir = '/home/mislav/projects/hanna/lib' - $:.unshift hanna_dir if File.exists? hanna_dir - require 'hanna/rdoctask' -rescue LoadError - require 'rake' - require 'rake/rdoctask' -end -load 'test/tasks.rake' - -desc 'Default: run unit tests.' -task :default => :test - -desc 'Generate RDoc documentation for the will_paginate plugin.' -Rake::RDocTask.new(:rdoc) do |rdoc| - rdoc.rdoc_files.include('README.rdoc', 'LICENSE', 'CHANGELOG'). - include('lib/**/*.rb'). - exclude('lib/will_paginate/named_scope*'). - exclude('lib/will_paginate/array.rb'). - exclude('lib/will_paginate/version.rb') - - rdoc.main = "README.rdoc" # page to start on - rdoc.title = "will_paginate documentation" - - rdoc.rdoc_dir = 'doc' # rdoc output folder - rdoc.options << '--inline-source' << '--charset=UTF-8' - rdoc.options << '--webcvs=http://github.com/mislav/will_paginate/tree/master/' -end - -desc %{Update ".manifest" with the latest list of project filenames. Respect\ -.gitignore by excluding everything that git ignores. Update `files` and\ -`test_files` arrays in "*.gemspec" file if it's present.} -task :manifest do - list = Dir['**/*'].sort - spec_file = Dir['*.gemspec'].first - list -= [spec_file] if spec_file - - File.read('.gitignore').each_line do |glob| - glob = glob.chomp.sub(/^\//, '') - list -= Dir[glob] - list -= Dir["#{glob}/**/*"] if File.directory?(glob) and !File.symlink?(glob) - puts "excluding #{glob}" - end - - if spec_file - spec = File.read spec_file - spec.gsub! /^(\s* s.(test_)?files \s* = \s* )( \[ [^\]]* \] | %w\( [^)]* \) )/mx do - assignment = $1 - bunch = $2 ? list.grep(/^test\//) : list - '%s%%w(%s)' % [assignment, bunch.join(' ')] - end - - File.open(spec_file, 'w') {|f| f << spec } - end - File.open('.manifest', 'w') {|f| f << list.join("\n") } -end - -task :examples do - %x(haml examples/index.haml examples/index.html) - %x(sass examples/pagination.sass examples/pagination.css) -end diff --git a/vendor/plugins/will_paginate/examples/apple-circle.gif b/vendor/plugins/will_paginate/examples/apple-circle.gif deleted file mode 100644 index df8cbf7c..00000000 Binary files a/vendor/plugins/will_paginate/examples/apple-circle.gif and /dev/null differ diff --git a/vendor/plugins/will_paginate/examples/index.haml b/vendor/plugins/will_paginate/examples/index.haml deleted file mode 100644 index fb41ac8a..00000000 --- a/vendor/plugins/will_paginate/examples/index.haml +++ /dev/null @@ -1,69 +0,0 @@ -!!! -%html -%head - %title Samples of pagination styling for will_paginate - %link{ :rel => 'stylesheet', :type => 'text/css', :href => 'pagination.css' } - %style{ :type => 'text/css' } - :sass - html - :margin 0 - :padding 0 - :background #999 - :font normal 76% "Lucida Grande", Verdana, Helvetica, sans-serif - body - :margin 2em - :padding 2em - :border 2px solid gray - :background white - :color #222 - h1 - :font-size 2em - :font-weight normal - :margin 0 0 1em 0 - h2 - :font-size 1.4em - :margin 1em 0 .5em 0 - pre - :font-size 13px - :font-family Monaco, "DejaVu Sans Mono", "Bitstream Vera Mono", "Courier New", monospace - -- pagination = '« Previous 1 2 3 4 5 6 7 8 9 … 29 30 Next »' -- pagination_no_page_links = '« Previous Next »' - -%body - %h1 Samples of pagination styling for will_paginate - %p - Find these styles in "examples/pagination.css" of will_paginate library. - There is a Sass version of it for all you sassy people. - %p - Read about good rules for pagination: - %a{ :href => 'http://kurafire.net/log/archive/2007/06/22/pagination-101' } Pagination 101 - %p - %em Warning: - page links below don't lead anywhere (so don't click on them). - - %h2 Unstyled pagination (ewww!) - %div= pagination - - %h2 Digg.com - .digg_pagination= pagination - - %h2 Digg-style, no page links - .digg_pagination= pagination_no_page_links - %p Code that renders this: - %pre= '%s' % %[<%= will_paginate @posts, :page_links => false %>].gsub('<', '<').gsub('>', '>')
-
- %h2 Digg-style, extra content
- .digg_pagination
- .page_info Displaying entries 1 - 6 of 180 in total
- = pagination
- %p Code that renders this:
- %pre= '%s' % %[- Find these styles in "examples/pagination.css" of will_paginate library. - There is a Sass version of it for all you sassy people. -
-- Read about good rules for pagination: - Pagination 101 -
-- Warning: - page links below don't lead anywhere (so don't click on them). -
-Code that renders this:
-
- <%= will_paginate @posts, :page_links => false %>
-
- Code that renders this:
-
- <div class="digg_pagination">
- <div clas="page_info">
- <%= page_entries_info @posts %>
- </div>
- <%= will_paginate @posts, :container => false %>
- </div>
-
- <%= trace.join "\n" %>
+ <%=h trace.join "\n" %>
#{h(object.to_yaml).gsub(" ", " ")}"
+ "#{h(object.to_yaml).gsub(" ", " ")}".html_safe
rescue Exception => e # errors from Marshal or YAML
# Object couldn't be dumped, perhaps because of singleton methods -- this is the fallback
- "#{h(object.inspect)}"
+ "#{h(object.inspect)}".html_safe
end
end
end
diff --git a/vendor/rails/actionpack/lib/action_view/helpers/form_helper.rb b/vendor/rails/actionpack/lib/action_view/helpers/form_helper.rb
index 4914ecc5..389212df 100644
--- a/vendor/rails/actionpack/lib/action_view/helpers/form_helper.rb
+++ b/vendor/rails/actionpack/lib/action_view/helpers/form_helper.rb
@@ -280,7 +280,7 @@ module ActionView
concat(form_tag(options.delete(:url) || {}, options.delete(:html) || {}))
fields_for(object_name, *(args << options), &proc)
- concat(''.html_safe!)
+ concat(''.html_safe)
end
def apply_form_for_options!(object_or_array, options) #:nodoc:
@@ -391,7 +391,7 @@ module ActionView
# accepts_nested_attributes_for :address, :allow_destroy => true
# end
#
- # Now, when you use a form element with the _delete parameter,
+ # Now, when you use a form element with the _destroy parameter,
# with a value that evaluates to +true+, you will destroy the associated
# model (eg. 1, '1', true, or 'true'):
#
@@ -399,7 +399,7 @@ module ActionView
# ...
# <% person_form.fields_for :address do |address_fields| %>
# ...
- # Delete: <%= address_fields.check_box :_delete %>
+ # Delete: <%= address_fields.check_box :_destroy %>
# <% end %>
# <% end %>
#
@@ -472,14 +472,14 @@ module ActionView
# end
#
# This will allow you to specify which models to destroy in the
- # attributes hash by adding a form element for the _delete
+ # attributes hash by adding a form element for the _destroy
# parameter with a value that evaluates to +true+
# (eg. 1, '1', true, or 'true'):
#
# <% form_for @person, :url => { :action => "update" } do |person_form| %>
# ...
# <% person_form.fields_for :projects do |project_fields| %>
- # Delete: <%= project_fields.check_box :_delete %>
+ # Delete: <%= project_fields.check_box :_destroy %>
# <% end %>
# <% end %>
def fields_for(record_or_name_or_array, *args, &block)
@@ -500,8 +500,9 @@ module ActionView
end
# Returns a label tag tailored for labelling an input field for a specified attribute (identified by +method+) on an object
- # assigned to the template (identified by +object+). The text of label will default to the attribute name unless you specify
- # it explicitly. Additional options on the label tag can be passed as a hash with +options+. These options will be tagged
+ # assigned to the template (identified by +object+). The text of label will default to the attribute name unless a translation
+ # is found in the current I18n locale (through views.labels.Dreamy days
", @response.body.strip end def test_content_for diff --git a/vendor/rails/actionpack/test/controller/cookie_test.rb b/vendor/rails/actionpack/test/controller/cookie_test.rb index e11f04ff..f517fdfe 100644 --- a/vendor/rails/actionpack/test/controller/cookie_test.rb +++ b/vendor/rails/actionpack/test/controller/cookie_test.rb @@ -2,6 +2,8 @@ require 'abstract_unit' class CookieTest < ActionController::TestCase class TestController < ActionController::Base + self.cookie_verifier_secret = "thisISverySECRET123" + def authenticate cookies["user_name"] = "david" end @@ -39,6 +41,22 @@ class CookieTest < ActionController::TestCase def authenticate_with_http_only cookies["user_name"] = { :value => "david", :httponly => true } end + + def authenticate_with_secure + cookies["user_name"] = { :value => "david", :secure => true } + end + + def set_permanent_cookie + cookies.permanent[:user_name] = "Jamie" + end + + def set_signed_cookie + cookies.signed[:user_id] = 45 + end + + def set_permanent_signed_cookie + cookies.permanent.signed[:remember_me] = 100 + end def rescue_action(e) raise unless ActionView::MissingTemplate # No templates here, and we don't care about the output @@ -80,6 +98,27 @@ class CookieTest < ActionController::TestCase assert_equal ["user_name=david; path=/; HttpOnly"], @response.headers["Set-Cookie"] assert_equal({"user_name" => "david"}, @response.cookies) end + + def test_setting_cookie_with_secure + @request.env["HTTPS"] = "on" + get :authenticate_with_secure + assert_equal ["user_name=david; path=/; secure"], @response.headers["Set-Cookie"] + assert_equal({"user_name" => "david"}, @response.cookies) + end + + def test_setting_cookie_with_secure_in_development + with_environment(:development) do + get :authenticate_with_secure + assert_equal ["user_name=david; path=/; secure"], @response.headers["Set-Cookie"] + assert_equal({"user_name" => "david"}, @response.cookies) + end + end + + def test_not_setting_cookie_with_secure + get :authenticate_with_secure + assert_not_equal ["user_name=david; path=/; secure"], @response.headers["Set-Cookie"] + assert_not_equal({"user_name" => "david"}, @response.cookies) + end def test_multiple_cookies get :set_multiple_cookies @@ -131,4 +170,39 @@ class CookieTest < ActionController::TestCase cookies = @controller.send(:cookies) assert_equal 'david', cookies['user_name'] end -end + + def test_permanent_cookie + get :set_permanent_cookie + assert_match /Jamie/, @response.headers["Set-Cookie"].first + assert_match %r(#{20.years.from_now.year}), @response.headers["Set-Cookie"].first + end + + def test_signed_cookie + get :set_signed_cookie + assert_equal 45, @controller.send(:cookies).signed[:user_id] + end + + def test_accessing_nonexistant_signed_cookie_should_not_raise_an_invalid_signature + get :set_signed_cookie + assert_nil @controller.send(:cookies).signed[:non_existant_attribute] + end + + def test_permanent_signed_cookie + get :set_permanent_signed_cookie + assert_match %r(#{20.years.from_now.year}), @response.headers["Set-Cookie"].first + assert_equal 100, @controller.send(:cookies).signed[:remember_me] + end + + private + def with_environment(enviroment) + old_rails = Object.const_get(:Rails) rescue nil + mod = Object.const_set(:Rails, Module.new) + (class << mod; self; end).instance_eval do + define_method(:env) { @_env ||= ActiveSupport::StringInquirer.new(enviroment.to_s) } + end + yield + ensure + Object.module_eval { remove_const(:Rails) } if defined?(Rails) + Object.const_set(:Rails, old_rails) if old_rails + end +end \ No newline at end of file diff --git a/vendor/rails/actionpack/test/controller/flash_test.rb b/vendor/rails/actionpack/test/controller/flash_test.rb index 81c724a5..daca8806 100644 --- a/vendor/rails/actionpack/test/controller/flash_test.rb +++ b/vendor/rails/actionpack/test/controller/flash_test.rb @@ -71,6 +71,18 @@ class FlashTest < ActionController::TestCase redirect_to :action => "std_action" @flash_copy = {}.update(flash) end + + def redirect_with_alert + redirect_to '/nowhere', :alert => "Beware the nowheres!" + end + + def redirect_with_notice + redirect_to '/somewhere', :notice => "Good luck in the somewheres!" + end + + def redirect_with_other_flashes + redirect_to '/wonderland', :flash => { :joyride => "Horses!" } + end end tests TestController @@ -144,4 +156,19 @@ class FlashTest < ActionController::TestCase get :std_action assert_nil session["flash"] end -end + + def test_redirect_to_with_alert + get :redirect_with_alert + assert_equal "Beware the nowheres!", @controller.send(:flash)[:alert] + end + + def test_redirect_to_with_notice + get :redirect_with_notice + assert_equal "Good luck in the somewheres!", @controller.send(:flash)[:notice] + end + + def test_redirect_to_with_other_flashes + get :redirect_with_other_flashes + assert_equal "Horses!", @controller.send(:flash)[:joyride] + end +end \ No newline at end of file diff --git a/vendor/rails/actionpack/test/controller/helper_test.rb b/vendor/rails/actionpack/test/controller/helper_test.rb index 5f36461b..49145864 100644 --- a/vendor/rails/actionpack/test/controller/helper_test.rb +++ b/vendor/rails/actionpack/test/controller/helper_test.rb @@ -87,7 +87,7 @@ class HelperTest < Test::Unit::TestCase assert_nothing_raised { @controller_class.helper { include HelperTest::TestHelper } } - assert [], missing_methods + assert_equal [], missing_methods end def test_helper_method diff --git a/vendor/rails/actionpack/test/controller/integration_test.rb b/vendor/rails/actionpack/test/controller/integration_test.rb index 3869f9db..d1bb19c3 100644 --- a/vendor/rails/actionpack/test/controller/integration_test.rb +++ b/vendor/rails/actionpack/test/controller/integration_test.rb @@ -227,6 +227,24 @@ class IntegrationTestTest < Test::Unit::TestCase end end +require 'active_record_unit' +# Tests that fixtures are accessible in the integration test sessions +class IntegrationTestWithFixtures < ActiveRecordTestCase + include ActionController::Integration::Runner + + fixtures :companies + + def test_fixtures_in_new_session + sym = :thirty_seven_signals + # fixtures are accessible in main session + assert_not_nil companies(sym) + + # create a new session and the fixtures should be accessible in it as well + session1 = open_session { |sess| } + assert_not_nil session1.companies(sym) + end +end + # Tests that integration tests don't call Controller test methods for processing. # Integration tests have their own setup and teardown. class IntegrationTestUsesCorrectClass < ActionController::IntegrationTest @@ -266,6 +284,14 @@ class IntegrationProcessTest < ActionController::IntegrationTest render :text => "foo(1i): #{params[:"foo(1i)"]}, foo(2i): #{params[:"foo(2i)"]}, filesize: #{params[:file].size}", :status => 200 end + def multipart_post_with_nested_params + render :text => "foo: #{params[:foo][0]}, #{params[:foo][1]}; [filesize: #{params[:file_list][0][:content].size}, filesize: #{params[:file_list][1][:content].size}]", :status => 200 + end + + def multipart_post_with_multiparameter_complex_params + render :text => "foo(1i): #{params[:"foo(1i)"]}, foo(2i): #{params[:"foo(2i)"]}, [filesize: #{params[:file_list][0][:content].size}, filesize: #{params[:file_list][1][:content].size}]", :status => 200 + end + def post render :text => "Created", :status => 201 end @@ -324,7 +350,6 @@ class IntegrationProcessTest < ActionController::IntegrationTest assert_equal "Gone", status_message assert_response 410 assert_response :gone - assert_equal "cookie_1=; path=/\ncookie_3=chocolate; path=/", headers["Set-Cookie"] assert_equal({"cookie_1"=>"", "cookie_2"=>"oatmeal", "cookie_3"=>"chocolate"}, cookies) assert_equal "Gone", response.body end @@ -406,6 +431,24 @@ class IntegrationProcessTest < ActionController::IntegrationTest end end + def test_multipart_post_with_nested_params + with_test_route_set do + post '/multipart_post_with_nested_params', :"foo" => ['a', 'b'], :file_list => [{:content => fixture_file_upload(FILES_DIR + "/mona_lisa.jpg", "image/jpg")}, {:content => fixture_file_upload(FILES_DIR + "/mona_lisa.jpg", "image/jpg")}] + + assert_equal 200, status + assert_equal "foo: a, b; [filesize: 159528, filesize: 159528]", response.body + end + end + + def test_multipart_post_with_multiparameter_complex_attribute_parameters + with_test_route_set do + post '/multipart_post_with_multiparameter_complex_params', :"foo(1i)" => "bar", :"foo(2i)" => "baz", :file_list => [{:content => fixture_file_upload(FILES_DIR + "/mona_lisa.jpg", "image/jpg")}, {:content => fixture_file_upload(FILES_DIR + "/mona_lisa.jpg", "image/jpg")}] + + assert_equal 200, status + assert_equal "foo(1i): bar, foo(2i): baz, [filesize: 159528, filesize: 159528]", response.body + end + end + def test_head with_test_route_set do head '/get' diff --git a/vendor/rails/actionpack/test/controller/localized_templates_test.rb b/vendor/rails/actionpack/test/controller/localized_templates_test.rb new file mode 100644 index 00000000..e89e5a81 --- /dev/null +++ b/vendor/rails/actionpack/test/controller/localized_templates_test.rb @@ -0,0 +1,24 @@ +require 'abstract_unit' + +class LocalizedController < ActionController::Base + def hello_world + end +end + +class LocalizedTemplatesTest < ActionController::TestCase + tests LocalizedController + + teardown { I18n.locale = :en } + + def test_localized_template_is_used + I18n.locale = :de + get :hello_world + assert_equal "Gutten Tag", @response.body + end + + def test_default_locale_template_is_used_when_locale_is_missing + I18n.locale = :dk + get :hello_world + assert_equal "Hello World", @response.body + end +end \ No newline at end of file diff --git a/vendor/rails/actionpack/test/controller/output_escaping_test.rb b/vendor/rails/actionpack/test/controller/output_escaping_test.rb new file mode 100644 index 00000000..43a8c05c --- /dev/null +++ b/vendor/rails/actionpack/test/controller/output_escaping_test.rb @@ -0,0 +1,19 @@ +require 'abstract_unit' + +class OutputEscapingTest < ActiveSupport::TestCase + + test "escape_html shouldn't die when passed nil" do + assert ERB::Util.h(nil).blank? + end + + test "escapeHTML should escape strings" do + assert_equal "<>"", ERB::Util.h("<>\"") + end + + test "escapeHTML shouldn't touch explicitly safe strings" do + # TODO this seems easier to compose and reason about, but + # this should be verified + assert_equal "<", ERB::Util.h("<".html_safe) + end + +end diff --git a/vendor/rails/actionpack/test/controller/rack_test.rb b/vendor/rails/actionpack/test/controller/rack_test.rb index aeace2b8..3d0643cf 100644 --- a/vendor/rails/actionpack/test/controller/rack_test.rb +++ b/vendor/rails/actionpack/test/controller/rack_test.rb @@ -219,7 +219,6 @@ class RackResponseTest < BaseRackTest "Content-Type" => "text/html; charset=utf-8", "Cache-Control" => "private, max-age=0, must-revalidate", "ETag" => '"65a8e27d8879283831b664bd8b7f0ad4"', - "Set-Cookie" => "", "Content-Length" => "13" }, headers) @@ -238,7 +237,6 @@ class RackResponseTest < BaseRackTest "Content-Type" => "text/html; charset=utf-8", "Cache-Control" => "private, max-age=0, must-revalidate", "ETag" => '"ebb5e89e8a94e9dd22abf5d915d112b2"', - "Set-Cookie" => "", "Content-Length" => "8" }, headers) end @@ -253,8 +251,7 @@ class RackResponseTest < BaseRackTest assert_equal 200, status assert_equal({ "Content-Type" => "text/html; charset=utf-8", - "Cache-Control" => "no-cache", - "Set-Cookie" => "" + "Cache-Control" => "no-cache" }, headers) parts = [] diff --git a/vendor/rails/actionpack/test/controller/reloader_test.rb b/vendor/rails/actionpack/test/controller/reloader_test.rb index e5305493..d78f8111 100644 --- a/vendor/rails/actionpack/test/controller/reloader_test.rb +++ b/vendor/rails/actionpack/test/controller/reloader_test.rb @@ -1,4 +1,5 @@ require 'abstract_unit' +require 'thread' class ReloaderTests < ActiveSupport::TestCase Reloader = ActionController::Reloader diff --git a/vendor/rails/actionpack/test/controller/render_test.rb b/vendor/rails/actionpack/test/controller/render_test.rb index 112e9efc..288260a2 100644 --- a/vendor/rails/actionpack/test/controller/render_test.rb +++ b/vendor/rails/actionpack/test/controller/render_test.rb @@ -652,6 +652,10 @@ class TestController < ActionController::Base render :partial => "customer_counter", :collection => [ Customer.new("david"), Customer.new("mary") ] end + def partial_collection_with_as_and_counter + render :partial => "customer_counter_with_as", :collection => [ Customer.new("david"), Customer.new("mary") ], :as => :client + end + def partial_collection_with_locals render :partial => "customer_greeting", :collection => [ Customer.new("david"), Customer.new("mary") ], :locals => { :greeting => "Bonjour" } end @@ -712,6 +716,11 @@ class TestController < ActionController::Base render :partial => "customer" end + def partial_with_implicit_local_assignment_and_nil_local + @customer = Customer.new("Marcel") + render :partial => "customer", :locals => { :customer => nil } + end + def render_call_to_partial_with_layout render :action => "calling_partial_with_layout" end @@ -1470,6 +1479,11 @@ class RenderTest < ActionController::TestCase assert_equal "david0mary1", @response.body end + def test_partial_collection_with_as_and_counter + get :partial_collection_with_as_and_counter + assert_equal "david0mary1", @response.body + end + def test_partial_collection_with_locals get :partial_collection_with_locals assert_equal "Bonjour: davidBonjour: mary", @response.body @@ -1534,6 +1548,13 @@ class RenderTest < ActionController::TestCase end end + def test_partial_with_implicit_local_assignment_and_nil_local + assert_not_deprecated do + get :partial_with_implicit_local_assignment_and_nil_local + assert_equal "Hello: Anonymous", @response.body + end + end + def test_render_missing_partial_template assert_raise(ActionView::MissingTemplate) do get :missing_partial @@ -1590,7 +1611,7 @@ class EtagRenderTest < ActionController::TestCase def test_render_blank_body_shouldnt_set_etag get :blank_response - assert !@response.etag? + assert !@response.etag?, @response.headers.inspect end def test_render_200_should_set_etag @@ -1609,7 +1630,7 @@ class EtagRenderTest < ActionController::TestCase def test_render_against_etag_request_should_have_no_content_length_when_match @request.if_none_match = etag_for("hello david") get :render_hello_world_from_variable - assert !@response.headers.has_key?("Content-Length"), @response.headers['Content-Length'] + assert_nil @response.headers["Content-Length"], @response.headers.inspect end def test_render_against_etag_request_should_200_when_no_match diff --git a/vendor/rails/actionpack/test/controller/request/multipart_params_parsing_test.rb b/vendor/rails/actionpack/test/controller/request/multipart_params_parsing_test.rb index cc81a87c..46aee378 100644 --- a/vendor/rails/actionpack/test/controller/request/multipart_params_parsing_test.rb +++ b/vendor/rails/actionpack/test/controller/request/multipart_params_parsing_test.rb @@ -14,6 +14,10 @@ class MultipartParamsParsingTest < ActionController::IntegrationTest def read render :text => "File: #{params[:uploaded_data].read}" end + + def read_complex + render :text => "File: #{params[:level0][:level1][0][:file_data].read}" + end end FIXTURE_PATH = File.dirname(__FILE__) + '/../../fixtures/multipart' @@ -133,6 +137,17 @@ class MultipartParamsParsingTest < ActionController::IntegrationTest end end + test "uploads and reads file in complex parameter" do + with_test_routing do + post '/read_complex', + :level0 => { + :level1 => [ { :file_data => fixture_file_upload(FIXTURE_PATH + "/hello.txt", "text/plain") } + ] + } + assert_equal "File: Hello", response.body + end + end + private def fixture(name) File.open(File.join(FIXTURE_PATH, name), 'rb') do |file| diff --git a/vendor/rails/actionpack/test/controller/request_forgery_protection_test.rb b/vendor/rails/actionpack/test/controller/request_forgery_protection_test.rb index c6ad4b92..75029057 100644 --- a/vendor/rails/actionpack/test/controller/request_forgery_protection_test.rb +++ b/vendor/rails/actionpack/test/controller/request_forgery_protection_test.rb @@ -23,6 +23,10 @@ module RequestForgeryProtectionActions render :text => 'pwn' end + def meta + render :inline => "<%= csrf_meta_tag %>" + end + def rescue_action(e) raise e end end @@ -32,6 +36,16 @@ class RequestForgeryProtectionController < ActionController::Base protect_from_forgery :only => :index end +class RequestForgeryProtectionControllerUsingOldBehaviour < ActionController::Base + include RequestForgeryProtectionActions + protect_from_forgery :only => %w(index meta) + + def handle_unverified_request + raise(ActionController::InvalidAuthenticityToken) + end +end + + class FreeCookieController < RequestForgeryProtectionController self.allow_forgery_protection = false @@ -54,158 +68,92 @@ end # common test methods module RequestForgeryProtectionTests - def teardown - ActionController::Base.request_forgery_protection_token = nil + def setup + @token = "cf50faa3fe97702ca1ae" + + ActiveSupport::SecureRandom.stubs(:base64).returns(@token) + ActionController::Base.request_forgery_protection_token = :authenticity_token end - + def test_should_render_form_with_token_tag - get :index - assert_select 'form>div>input[name=?][value=?]', 'authenticity_token', @token - end - - def test_should_render_button_to_with_token_tag - get :show_button - assert_select 'form>div>input[name=?][value=?]', 'authenticity_token', @token - end - - def test_should_render_remote_form_with_only_one_token_parameter - get :remote_form - assert_equal 1, @response.body.scan(@token).size - end - - def test_should_allow_get - get :index - assert_response :success - end - - def test_should_allow_post_without_token_on_unsafe_action - post :unsafe - assert_response :success - end - - def test_should_not_allow_html_post_without_token - @request.env['CONTENT_TYPE'] = Mime::URL_ENCODED_FORM.to_s - assert_raise(ActionController::InvalidAuthenticityToken) { post :index, :format => :html } - end - - def test_should_not_allow_html_put_without_token - @request.env['CONTENT_TYPE'] = Mime::URL_ENCODED_FORM.to_s - assert_raise(ActionController::InvalidAuthenticityToken) { put :index, :format => :html } - end - - def test_should_not_allow_html_delete_without_token - @request.env['CONTENT_TYPE'] = Mime::URL_ENCODED_FORM.to_s - assert_raise(ActionController::InvalidAuthenticityToken) { delete :index, :format => :html } - end - - def test_should_allow_api_formatted_post_without_token - assert_nothing_raised do - post :index, :format => 'xml' + assert_not_blocked do + get :index end + assert_select 'form>div>input[name=?][value=?]', 'authenticity_token', @token end - def test_should_not_allow_api_formatted_put_without_token - assert_nothing_raised do - put :index, :format => 'xml' + def test_should_render_button_to_with_token_tag + assert_not_blocked do + get :show_button end + assert_select 'form>div>input[name=?][value=?]', 'authenticity_token', @token end - def test_should_allow_api_formatted_delete_without_token - assert_nothing_raised do - delete :index, :format => 'xml' - end + def test_should_allow_get + assert_not_blocked { get :index } end - def test_should_not_allow_api_formatted_post_sent_as_url_encoded_form_without_token - assert_raise(ActionController::InvalidAuthenticityToken) do - @request.env['CONTENT_TYPE'] = Mime::URL_ENCODED_FORM.to_s - post :index, :format => 'xml' - end + def test_should_allow_post_without_token_on_unsafe_action + assert_not_blocked { post :unsafe } end - def test_should_not_allow_api_formatted_put_sent_as_url_encoded_form_without_token - assert_raise(ActionController::InvalidAuthenticityToken) do - @request.env['CONTENT_TYPE'] = Mime::URL_ENCODED_FORM.to_s - put :index, :format => 'xml' - end + def test_should_not_allow_post_without_token + assert_blocked { post :index } end - def test_should_not_allow_api_formatted_delete_sent_as_url_encoded_form_without_token - assert_raise(ActionController::InvalidAuthenticityToken) do - @request.env['CONTENT_TYPE'] = Mime::URL_ENCODED_FORM.to_s - delete :index, :format => 'xml' - end + def test_should_not_allow_post_without_token_irrespective_of_format + assert_blocked { post :index, :format=>'xml' } end - def test_should_not_allow_api_formatted_post_sent_as_multipart_form_without_token - assert_raise(ActionController::InvalidAuthenticityToken) do - @request.env['CONTENT_TYPE'] = Mime::MULTIPART_FORM.to_s - post :index, :format => 'xml' - end + def test_should_not_allow_put_without_token + assert_blocked { put :index } end - def test_should_not_allow_api_formatted_put_sent_as_multipart_form_without_token - assert_raise(ActionController::InvalidAuthenticityToken) do - @request.env['CONTENT_TYPE'] = Mime::MULTIPART_FORM.to_s - put :index, :format => 'xml' - end + def test_should_not_allow_delete_without_token + assert_blocked { delete :index } end - def test_should_not_allow_api_formatted_delete_sent_as_multipart_form_without_token - assert_raise(ActionController::InvalidAuthenticityToken) do - @request.env['CONTENT_TYPE'] = Mime::MULTIPART_FORM.to_s - delete :index, :format => 'xml' - end + def test_should_not_allow_xhr_post_without_token + assert_blocked { xhr :post, :index } end - - def test_should_allow_xhr_post_without_token - assert_nothing_raised { xhr :post, :index } - end - - def test_should_allow_xhr_put_without_token - assert_nothing_raised { xhr :put, :index } - end - - def test_should_allow_xhr_delete_without_token - assert_nothing_raised { xhr :delete, :index } - end - - def test_should_allow_xhr_post_with_encoded_form_content_type_without_token - @request.env['CONTENT_TYPE'] = Mime::URL_ENCODED_FORM.to_s - assert_nothing_raised { xhr :post, :index } - end - + def test_should_allow_post_with_token - post :index, :authenticity_token => @token - assert_response :success + assert_not_blocked { post :index, :authenticity_token => @token } end def test_should_allow_put_with_token - put :index, :authenticity_token => @token - assert_response :success + assert_not_blocked { put :index, :authenticity_token => @token } end def test_should_allow_delete_with_token - delete :index, :authenticity_token => @token + assert_not_blocked { delete :index, :authenticity_token => @token } + end + + def test_should_allow_post_with_token_in_header + @request.env['HTTP_X_CSRF_TOKEN'] = @token + assert_not_blocked { post :index } + end + + def test_should_allow_delete_with_token_in_header + @request.env['HTTP_X_CSRF_TOKEN'] = @token + assert_not_blocked { delete :index } + end + + def test_should_allow_put_with_token_in_header + @request.env['HTTP_X_CSRF_TOKEN'] = @token + assert_not_blocked { put :index } + end + + def assert_blocked + session[:something_like_user_id] = 1 + yield + assert_nil session[:something_like_user_id], "session values are still present" assert_response :success end - def test_should_allow_post_with_xml - @request.env['CONTENT_TYPE'] = Mime::XML.to_s - post :index, :format => 'xml' - assert_response :success - end - - def test_should_allow_put_with_xml - @request.env['CONTENT_TYPE'] = Mime::XML.to_s - put :index, :format => 'xml' - assert_response :success - end - - def test_should_allow_delete_with_xml - @request.env['CONTENT_TYPE'] = Mime::XML.to_s - delete :index, :format => 'xml' + def assert_not_blocked + assert_nothing_raised { yield } assert_response :success end end @@ -214,15 +162,20 @@ end class RequestForgeryProtectionControllerTest < ActionController::TestCase include RequestForgeryProtectionTests - def setup - @controller = RequestForgeryProtectionController.new - @request = ActionController::TestRequest.new - @request.format = :html - @response = ActionController::TestResponse.new - @token = "cf50faa3fe97702ca1ae" - ActiveSupport::SecureRandom.stubs(:base64).returns(@token) - ActionController::Base.request_forgery_protection_token = :authenticity_token + test 'should emit a csrf-token meta tag' do + ActiveSupport::SecureRandom.stubs(:base64).returns(@token + '<=?') + get :meta + assert_equal %(\n), @response.body + end +end + +class RequestForgeryProtectionControllerUsingOldBehaviourTest < ActionController::TestCase + include RequestForgeryProtectionTests + def assert_blocked + assert_raises(ActionController::InvalidAuthenticityToken) do + yield + end end end @@ -251,15 +204,30 @@ class FreeCookieControllerTest < ActionController::TestCase assert_nothing_raised { send(method, :index)} end end + + test 'should not emit a csrf-token meta tag' do + get :meta + assert_blank @response.body + end end + + + + class CustomAuthenticityParamControllerTest < ActionController::TestCase def setup + ActionController::Base.request_forgery_protection_token = :custom_token_name + super + end + + def teardown ActionController::Base.request_forgery_protection_token = :authenticity_token + super end def test_should_allow_custom_token - post :index, :authenticity_token => 'foobar' + post :index, :custom_token_name => 'foobar' assert_response :ok end end diff --git a/vendor/rails/actionpack/test/controller/rescue_test.rb b/vendor/rails/actionpack/test/controller/rescue_test.rb index 5709f37e..58fccdce 100644 --- a/vendor/rails/actionpack/test/controller/rescue_test.rb +++ b/vendor/rails/actionpack/test/controller/rescue_test.rb @@ -281,17 +281,22 @@ class RescueControllerTest < ActionController::TestCase end def test_local_request_when_remote_addr_is_localhost - @controller.expects(:request).returns(@request).at_least_once - with_remote_addr '127.0.0.1' do - assert @controller.send(:local_request?) + @controller.expects(:request).returns(@request).at_least(10) + ['127.0.0.1', '127.0.0.127', '::1', '0:0:0:0:0:0:0:1', '0:0:0:0:0:0:0:1%0'].each do |ip_address| + with_remote_addr ip_address do + assert @controller.send(:local_request?) + end end end def test_local_request_when_remote_addr_isnt_locahost - @controller.expects(:request).returns(@request) + @controller.expects(:request).returns(@request).at_least(4) with_remote_addr '1.2.3.4' do assert !@controller.send(:local_request?) end + with_remote_addr '2002::102:304' do + assert !@controller.send(:local_request?) + end end def test_rescue_responses diff --git a/vendor/rails/actionpack/test/controller/routing_test.rb b/vendor/rails/actionpack/test/controller/routing_test.rb index 81b015b7..fc4804f7 100644 --- a/vendor/rails/actionpack/test/controller/routing_test.rb +++ b/vendor/rails/actionpack/test/controller/routing_test.rb @@ -1,3 +1,4 @@ +# encoding: us-ascii require 'abstract_unit' require 'controller/fake_controllers' require 'action_controller/routing/route_set' diff --git a/vendor/rails/actionpack/test/controller/send_file_test.rb b/vendor/rails/actionpack/test/controller/send_file_test.rb index f61bbc60..a8e1afc7 100644 --- a/vendor/rails/actionpack/test/controller/send_file_test.rb +++ b/vendor/rails/actionpack/test/controller/send_file_test.rb @@ -73,7 +73,7 @@ class SendFileTest < ActionController::TestCase assert_equal @controller.file_path, response.headers['X-Sendfile'] assert response.body.blank? - assert !response.etag? + assert !response.etag?, response.headers.inspect end def test_data diff --git a/vendor/rails/actionpack/test/controller/session/cookie_store_test.rb b/vendor/rails/actionpack/test/controller/session/cookie_store_test.rb index 40fcd568..b7b922c3 100644 --- a/vendor/rails/actionpack/test/controller/session/cookie_store_test.rb +++ b/vendor/rails/actionpack/test/controller/session/cookie_store_test.rb @@ -6,7 +6,6 @@ class CookieStoreTest < ActionController::IntegrationTest SessionSecret = 'b3c631c314c0bbca50c1b2843150fe33' DispatcherApp = ActionController::Dispatcher.new - CookieStoreApp = ActionController::Session::CookieStore.new(DispatcherApp, :key => SessionKey, :secret => SessionSecret) Verifier = ActiveSupport::MessageVerifier.new(SessionSecret, 'SHA1') @@ -34,6 +33,15 @@ class CookieStoreTest < ActionController::IntegrationTest render :text => "foo: #{session[:foo].inspect}; id: #{request.session_options[:id]}" end + def get_session_id_only + render :text => "id: #{request.session_options[:id]}" + end + + def call_session_clear + session.clear + head :ok + end + def call_reset_session reset_session head :ok @@ -44,11 +52,13 @@ class CookieStoreTest < ActionController::IntegrationTest head :ok end - def rescue_action(e) raise end - end + def set_session_value_and_cookie + cookies["foo"] = "bar" + session[:foo] = "bar" + render :text => Rack::Utils.escape(Verifier.generate(session.to_hash)) + end - def setup - @integration_session = open_session(CookieStoreApp) + def rescue_action(e) raise end end def test_raises_argument_error_if_missing_session_key @@ -121,6 +131,10 @@ class CookieStoreTest < ActionController::IntegrationTest get '/get_session_id' assert_response :success assert_equal "foo: \"bar\"; id: #{session_id}", response.body + + get '/get_session_id_only' + assert_response :success + assert_equal "id: #{session_id}", response.body, "should be able to read session id without accessing the session hash" end end @@ -133,6 +147,23 @@ class CookieStoreTest < ActionController::IntegrationTest end end + def test_does_not_set_secure_cookies_over_http + with_test_route_set(:secure => true) do + get '/set_session_value' + assert_response :success + assert_equal nil, headers['Set-Cookie'] + end + end + + def test_does_set_secure_cookies_over_https + with_test_route_set(:secure => true) do + get '/set_session_value', nil, 'HTTPS' => 'on' + assert_response :success + assert_equal "_myapp_session=#{response.body}; path=/; secure; HttpOnly", + headers['Set-Cookie'] + end + end + def test_close_raises_when_data_overflows with_test_route_set do assert_raise(ActionController::Session::CookieStore::CookieOverflow) { @@ -145,7 +176,7 @@ class CookieStoreTest < ActionController::IntegrationTest with_test_route_set do get '/no_session_access' assert_response :success - assert_equal "", headers['Set-Cookie'] + assert_equal nil, headers['Set-Cookie'] end end @@ -155,7 +186,7 @@ class CookieStoreTest < ActionController::IntegrationTest "fef868465920f415f2c0652d6910d3af288a0367" get '/no_session_access' assert_response :success - assert_equal "", headers['Set-Cookie'] + assert_equal nil, headers['Set-Cookie'] end end @@ -169,7 +200,7 @@ class CookieStoreTest < ActionController::IntegrationTest get '/call_reset_session' assert_response :success - assert_not_equal [], headers['Set-Cookie'] + assert_not_equal "", headers['Set-Cookie'] assert_not_equal session_payload, cookies[SessionKey] get '/get_session_value' @@ -178,6 +209,57 @@ class CookieStoreTest < ActionController::IntegrationTest end end + def test_setting_session_value_after_session_clear + with_test_route_set do + get '/set_session_value' + assert_response :success + session_payload = response.body + assert_equal "_myapp_session=#{response.body}; path=/; HttpOnly", + headers['Set-Cookie'] + + get '/call_session_clear' + assert_response :success + + get '/get_session_value' + assert_response :success + assert_equal 'foo: nil', response.body + end + end + + def test_getting_from_nonexistent_session + with_test_route_set do + get '/get_session_value' + assert_response :success + assert_equal 'foo: nil', response.body + assert_nil headers['Set-Cookie'], "should only create session on write, not read" + end + end + + # {:foo=>#Dreamy days
<% end %> -<%= days %> \ No newline at end of file +<%= days %> diff --git a/vendor/rails/actionpack/test/fixtures/test/scoped_array_translation.erb b/vendor/rails/actionpack/test/fixtures/test/scoped_array_translation.erb new file mode 100644 index 00000000..cb07fca8 --- /dev/null +++ b/vendor/rails/actionpack/test/fixtures/test/scoped_array_translation.erb @@ -0,0 +1 @@ +<%= t(['.foo', '.bar']).join(", ") %> \ No newline at end of file diff --git a/vendor/rails/actionpack/test/fixtures/test/translation.erb b/vendor/rails/actionpack/test/fixtures/test/translation.erb new file mode 100644 index 00000000..81a837d1 --- /dev/null +++ b/vendor/rails/actionpack/test/fixtures/test/translation.erb @@ -0,0 +1 @@ +<%= t('.helper') %> \ No newline at end of file diff --git a/vendor/rails/actionpack/test/fixtures/test/utf8.html.erb b/vendor/rails/actionpack/test/fixtures/test/utf8.html.erb index 0b4d19aa..ac98c2f0 100644 --- a/vendor/rails/actionpack/test/fixtures/test/utf8.html.erb +++ b/vendor/rails/actionpack/test/fixtures/test/utf8.html.erb @@ -1,2 +1,4 @@ -Русский текст -日本語のテキスト \ No newline at end of file +Русский <%= render :partial => 'test/utf8_partial' %> +<%= "日".encoding %> +<%= @output_buffer.encoding %> +<%= __ENCODING__ %> diff --git a/vendor/rails/actionpack/test/fixtures/test/utf8_magic.html.erb b/vendor/rails/actionpack/test/fixtures/test/utf8_magic.html.erb new file mode 100644 index 00000000..257279c2 --- /dev/null +++ b/vendor/rails/actionpack/test/fixtures/test/utf8_magic.html.erb @@ -0,0 +1,5 @@ +<%# encoding: utf-8 -%> +Русский <%= render :partial => 'test/utf8_partial_magic' %> +<%= "日".encoding %> +<%= @output_buffer.encoding %> +<%= __ENCODING__ %> diff --git a/vendor/rails/actionpack/test/fixtures/test/utf8_magic_with_bare_partial.html.erb b/vendor/rails/actionpack/test/fixtures/test/utf8_magic_with_bare_partial.html.erb new file mode 100644 index 00000000..cb22692f --- /dev/null +++ b/vendor/rails/actionpack/test/fixtures/test/utf8_magic_with_bare_partial.html.erb @@ -0,0 +1,5 @@ +<%# encoding: utf-8 -%> +Русский <%= render :partial => 'test/utf8_partial' %> +<%= "日".encoding %> +<%= @output_buffer.encoding %> +<%= __ENCODING__ %> diff --git a/vendor/rails/actionpack/test/template/active_record_helper_i18n_test.rb b/vendor/rails/actionpack/test/template/active_record_helper_i18n_test.rb index 4b6e8ddc..cac04c8e 100644 --- a/vendor/rails/actionpack/test/template/active_record_helper_i18n_test.rb +++ b/vendor/rails/actionpack/test/template/active_record_helper_i18n_test.rb @@ -2,7 +2,7 @@ require 'abstract_unit' class ActiveRecordHelperI18nTest < Test::Unit::TestCase include ActionView::Helpers::ActiveRecordHelper - + attr_reader :request def setup @object = stub :errors => stub(:count => 1, :full_messages => ['full_messages']) @@ -35,10 +35,17 @@ class ActiveRecordHelperI18nTest < Test::Unit::TestCase I18n.expects(:t).with('', :default => '', :count => 1, :scope => [:activerecord, :models]).once.returns '' error_messages_for(:object => @object, :locale => 'en') end - + def test_error_messages_for_given_object_name_it_translates_object_name I18n.expects(:t).with(:header, :locale => 'en', :scope => [:activerecord, :errors, :template], :count => 1, :model => @object_name).returns "1 error prohibited this #{@object_name} from being saved" I18n.expects(:t).with(@object_name, :default => @object_name, :count => 1, :scope => [:activerecord, :models]).once.returns @object_name error_messages_for(:object => @object, :locale => 'en', :object_name => @object_name) end + + def test_error_messages_for_given_object_name_with_underscore_it_translates_object_name + I18n.expects(:t).with('bank_account', :default => 'bank account', :count => 1, :scope => [:activerecord, :models]).once.returns 'bank account' + I18n.expects(:t).with(:header, :locale => 'en', :scope => [:activerecord, :errors, :template], :count => 1, :model => 'bank account').returns "1 error prohibited this bank account from being saved" + error_messages_for(:object => @object, :locale => 'en', :object_name => 'bank_account') + end end + diff --git a/vendor/rails/actionpack/test/template/asset_tag_helper_test.rb b/vendor/rails/actionpack/test/template/asset_tag_helper_test.rb index 46e6129a..a4e0d264 100644 --- a/vendor/rails/actionpack/test/template/asset_tag_helper_test.rb +++ b/vendor/rails/actionpack/test/template/asset_tag_helper_test.rb @@ -128,7 +128,6 @@ class AssetTagHelperTest < ActionView::TestCase ImageLinkToTag = { %(image_tag("xml.png")) => %(
),
- %(image_tag("..jpg")) => %(
),
%(image_tag("rss.gif", :alt => "rss syndication")) => %(
),
%(image_tag("gold.png", :size => "45x70")) => %(") + assert_equal "<p>", escaped + assert escaped.html_safe? + end + + def test_html_escape_passes_html_escpe_unmodified + escaped = h("
".html_safe) + assert_equal "
", escaped
+ assert escaped.html_safe?
+ end
def test_rest_in_ascii
(0..127).to_a.map(&:chr).each do |chr|
diff --git a/vendor/rails/actionpack/test/template/form_helper_test.rb b/vendor/rails/actionpack/test/template/form_helper_test.rb
index f22302d3..5b62674f 100644
--- a/vendor/rails/actionpack/test/template/form_helper_test.rb
+++ b/vendor/rails/actionpack/test/template/form_helper_test.rb
@@ -92,6 +92,19 @@ class FormHelperTest < ActionView::TestCase
tests ActionView::Helpers::FormHelper
def setup
+ super
+
+ # Create "label" locale for testing I18n label helpers
+ I18n.backend.store_translations 'label', {
+ :helpers => {
+ :label => {
+ :post => {
+ :body => "Write entire text here"
+ }
+ }
+ }
+ }
+
@post = Post.new
@comment = Comment.new
def @post.errors()
@@ -112,6 +125,10 @@ class FormHelperTest < ActionView::TestCase
@post.secret = 1
@post.written_on = Date.new(2004, 6, 15)
+ def Post.human_attribute_name(attribute)
+ attribute.to_s == "cost" ? "Total cost" : attribute.to_s.humanize
+ end
+
@controller = Class.new do
attr_reader :url_for_options
def url_for(options)
@@ -137,6 +154,27 @@ class FormHelperTest < ActionView::TestCase
assert_dom_equal('', label(:post, :secret?))
end
+ def test_label_with_locales_strings
+ old_locale, I18n.locale = I18n.locale, :label
+ assert_dom_equal('', label("post", "body"))
+ ensure
+ I18n.locale = old_locale
+ end
+
+ def test_label_with_human_attribute_name
+ old_locale, I18n.locale = I18n.locale, :label
+ assert_dom_equal('', label(:post, :cost))
+ ensure
+ I18n.locale = old_locale
+ end
+
+ def test_label_with_locales_symbols
+ old_locale, I18n.locale = I18n.locale, :label
+ assert_dom_equal('', label(:post, :body))
+ ensure
+ I18n.locale = old_locale
+ end
+
def test_label_with_for_attribute_as_symbol
assert_dom_equal('', label(:post, :title, nil, :for => "my_for"))
end
@@ -1102,12 +1140,12 @@ class FormHelperTest < ActionView::TestCase
class LabelledFormBuilder < ActionView::Helpers::FormBuilder
(field_helpers - %w(hidden_field)).each do |selector|
- src = <<-END_SRC
+ src, line = <<-END_SRC, __LINE__ + 1
def #{selector}(field, *args, &proc)
- (" " + super + "
").html_safe!
+ (" " + super + "
").html_safe
end
END_SRC
- class_eval src, __FILE__, __LINE__
+ class_eval src, __FILE__, line
end
end
@@ -1182,6 +1220,22 @@ class FormHelperTest < ActionView::TestCase
assert_dom_equal expected, output_buffer
end
+
+ def test_default_form_builder_without_object
+
+ form_for(:post) do |f|
+ concat f.error_message_on('author_name')
+ concat f.error_messages
+ end
+
+ expected = %(
para 1
\n\npara 2
), simple_format("para 1\n\npara 2", :class => 'test') end + def test_simple_format_should_be_html_safe + assert simple_format(" test with html tags ").html_safe? + end + + def test_simple_format_should_not_escape_safe_input + assert_equal "test with safe string
", simple_format(" test with safe string ".html_safe) + end + def test_truncate assert_equal "Hello World!", truncate("Hello World!", :length => 12) assert_equal "Hello Wor...", truncate("Hello World!!", :length => 12) @@ -224,6 +233,8 @@ class TextHelperTest < ActionView::TestCase assert_equal("2 counts", pluralize('2', "count")) assert_equal("1,066 counts", pluralize('1,066', "count")) assert_equal("1.25 counts", pluralize('1.25', "count")) + assert_equal("1.0 count", pluralize('1.0', "count")) + assert_equal("1.00 count", pluralize('1.00', "count")) assert_equal("2 counters", pluralize(2, "count", "counters")) assert_equal("0 counters", pluralize(nil, "count", "counters")) assert_equal("2 people", pluralize(2, "person")) @@ -285,6 +296,7 @@ class TextHelperTest < ActionView::TestCase assert_equal %(Link #{link_result_with_options}
), auto_link("Link #{link_raw}
", :all, {:target => "_blank"}) assert_equal %(Go to #{link_result}.), auto_link(%(Go to #{link_raw}.)) assert_equal %(Go to #{link_result}, then say hello to #{email_result}.
), auto_link(%(Go to #{link_raw}, then say hello to #{email_raw}.
)) + assert_equal %(#{link_result} #{link_result}), auto_link(%(#{link_result} #{link_raw})) email2_raw = '+david@loudthinking.com' email2_result = %{#{email2_raw}} @@ -356,11 +368,39 @@ class TextHelperTest < ActionView::TestCase assert_equal %(#{link10_result} Link
), auto_link("#{link10_raw} Link
") end + def test_auto_link_other_protocols + ftp_raw = 'ftp://example.com/file.txt' + assert_equal %(Download #{generate_result(ftp_raw)}), auto_link("Download #{ftp_raw}") + + file_scheme = 'file:///home/username/RomeoAndJuliet.pdf' + z39_scheme = 'z39.50r://host:696/db' + chrome_scheme = 'chrome://package/section/path' + view_source = 'view-source:http://en.wikipedia.org/wiki/URI_scheme' + assert_equal generate_result(z39_scheme), auto_link(z39_scheme) + assert_equal generate_result(chrome_scheme), auto_link(chrome_scheme) + assert_equal generate_result(view_source), auto_link(view_source) + end + def test_auto_link_already_linked linked1 = generate_result('Ruby On Rails', 'http://www.rubyonrails.com') - linked2 = generate_result('www.rubyonrails.com', 'http://www.rubyonrails.com') + linked2 = %('www.example.com') + linked3 = %('www.example.com') + linked4 = %('www.example.com') + linked5 = %('close www.example.com') assert_equal linked1, auto_link(linked1) assert_equal linked2, auto_link(linked2) + assert_equal linked3, auto_link(linked3) + assert_equal linked4, auto_link(linked4) + assert_equal linked5, auto_link(linked5) + + linked_email = %Q(Mail me) + assert_equal linked_email, auto_link(linked_email) + end + + def test_auto_link_within_tags + link_raw = 'http://www.rubyonrails.org/images/rails.png' + link_result = %Q(#{url[0...7]}...
#{email[0...7]}...
#{url}
#{email}
), mail_to('feedback@example.com', '
')
+ assert_dom_equal %(
), mail_to('feedback@example.com', '
'.html_safe)
end
def test_mail_to_with_hex
@@ -357,8 +361,8 @@ class UrlHelperTest < ActionView::TestCase
assert_dom_equal "me(at)domain.com", mail_to("me@domain.com", nil, :encode => "hex", :replace_at => "(at)")
assert_dom_equal "My email", mail_to("me@domain.com", "My email", :encode => "hex", :replace_at => "(at)")
assert_dom_equal "me(at)domain(dot)com", mail_to("me@domain.com", nil, :encode => "hex", :replace_at => "(at)", :replace_dot => "(dot)")
- assert_dom_equal "", mail_to("me@domain.com", "My email", :encode => "javascript", :replace_at => "(at)", :replace_dot => "(dot)")
- assert_dom_equal "", mail_to("me@domain.com", nil, :encode => "javascript", :replace_at => "(at)", :replace_dot => "(dot)")
+ assert_dom_equal "", mail_to("me@domain.com", "My email", :encode => "javascript", :replace_at => "(at)", :replace_dot => "(dot)")
+ assert_dom_equal "", mail_to("me@domain.com", nil, :encode => "javascript", :replace_at => "(at)", :replace_dot => "(dot)")
end
def protect_against_forgery?
@@ -562,6 +566,10 @@ class PolymorphicControllerTest < ActionView::TestCase
render :inline => "<%= url_for([@workshop, @session]) %>\n<%= link_to('Session', [@workshop, @session]) %>"
end
+ def show_workshop_of_nil_sessions
+ render :inline => "<%= workshop_sessions_path(nil) %>"
+ end
+
def rescue_action(e) raise e end
end
@@ -608,6 +616,16 @@ class PolymorphicControllerTest < ActionView::TestCase
end
end
+ def test_existing_nested_resource_with_nil_id
+ @controller = SessionsController.new
+
+ with_restful_routing do
+ assert_raise ActionController::RoutingError do
+ get :show_workshop_of_nil_sessions
+ end
+ end
+ end
+
protected
def with_restful_routing
with_routing do |set|
@@ -615,6 +633,7 @@ class PolymorphicControllerTest < ActionView::TestCase
map.resources :workshops do |w|
w.resources :sessions
end
+ map.show_workshop_of_nil_sessions 'sessions/show_workshop_of_nil_sessions', :controller => 'sessions', :action => 'show_workshop_of_nil_sessions'
end
yield
end
diff --git a/vendor/rails/actionpack/test/view/safe_buffer_test.rb b/vendor/rails/actionpack/test/view/safe_buffer_test.rb
deleted file mode 100644
index 0b378aeb..00000000
--- a/vendor/rails/actionpack/test/view/safe_buffer_test.rb
+++ /dev/null
@@ -1,36 +0,0 @@
-require 'abstract_unit'
-
-class SafeBufferTest < ActionView::TestCase
- def setup
- @buffer = ActionView::SafeBuffer.new
- end
-
- test "Should look like a string" do
- assert @buffer.is_a?(String)
- assert_equal "", @buffer
- end
-
- test "Should escape a raw string which is passed to them" do
- @buffer << "
-
-
-
-
-
-
- <%= p.name %>
<% end %>" -
- -WARNING: There is seldom any good reason to use this option. Mixing ERB into your controllers defeats the MVC orientation of Rails and will make it harder for other developers to follow the logic of your project. Use a separate erb view instead. - -By default, inline rendering uses ERb. You can force it to use Builder instead with the +:type+ option: - - -render :inline => - "xml.p {'Horrid coding practice!'}", :type => :builder - - -h5. Using +render+ with +:update+ - -You can also render javascript-based page updates inline using the +:update+ option to +render+: - - -render :update do |page| - page.replace_html 'warning', "Invalid options supplied" -end - - -WARNING: Placing javascript updates in your controller may seem to streamline small updates, but it defeats the MVC orientation of Rails and will make it harder for other developers to follow the logic of your project. We recommend using a separate rjs template instead, no matter how small the update. - -h5. Rendering Text - -You can send plain text - with no markup at all - back to the browser by using the +:text+ option to +render+: - - -render :text => "OK" - - -TIP: Rendering pure text is most useful when you're responding to AJAX or web service requests that are expecting something other than proper HTML. - -NOTE: By default, if you use the +:text+ option, the file is rendered without using the current layout. If you want Rails to put the text into the current layout, you need to add the +:layout => true+ option - -h5. Rendering JSON - -JSON is a javascript data format used by many AJAX libraries. Rails has built-in support for converting objects to JSON and rendering that JSON back to the browser: - - -render :json => @product - - -TIP: You don't need to call +to_json+ on the object that you want to render. If you use the +:json+ option, +render+ will automatically call +to_json+ for you. - -h5. Rendering XML - -Rails also has built-in support for converting objects to XML and rendering that XML back to the caller: - - -render :xml => @product - - -TIP: You don't need to call +to_xml+ on the object that you want to render. If you use the +:xml+ option, +render+ will automatically call +to_xml+ for you. - -h5. Rendering Vanilla JavaScript - -Rails can render vanilla JavaScript (as an alternative to using +update+ with n +.rjs+ file): - - -render :js => "alert('Hello Rails');" - - -This will send the supplied string to the browser with a MIME type of +text/javascript+. - -h5. Options for +render+ - -Calls to the +render+ method generally accept four options: - -* +:content_type+ -* +:layout+ -* +:status+ -* +:location+ - -h6. The +:content_type+ Option - -By default, Rails will serve the results of a rendering operation with the MIME content-type of +text/html+ (or +application/json+ if you use the +:json+ option, or +application/xml+ for the +:xml+ option.). There are times when you might like to change this, and you can do so by setting the +:content_type+ option: - - -render :file => filename, :content_type => 'application/rss' - - -h6. The +:layout+ Option - -With most of the options to +render+, the rendered content is displayed as part of the current layout. You'll learn more about layouts and how to use them later in this guide. - -You can use the +:layout+ option to tell Rails to use a specific file as the layout for the current action: - - -render :layout => 'special_layout' - - -You can also tell Rails to render with no layout at all: - - -render :layout => false - - -h6. The +:status+ Option - -Rails will automatically generate a response with the correct HTML status code (in most cases, this is +200 OK+). You can use the +:status+ option to change this: - - -render :status => 500 -render :status => :forbidden - - -Rails understands either numeric status codes or symbols for status codes. You can find its list of status codes in +actionpack/lib/action_controller/status_codes.rb+. You can also see there how Rails maps symbols to status codes. - -h6. The +:location+ Option - -You can use the +:location+ option to set the HTTP +Location+ header: - - -render :xml => photo, :location => photo_url(photo) - - -h5. Finding Layouts - -To find the current layout, Rails first looks for a file in +app/views/layouts+ with the same base name as the controller. For example, rendering actions from the +PhotosController+ class will use +/app/views/layouts/photos.html.erb+ (or +app/views/layouts/photos.builder+). If there is no such controller-specific layout, Rails will use +/app/views/layouts/application.html.erb+ ot +/app/views/layouts/application.builder+. If there is no +.erb+ layout, Rails will use a +.builder+ layout if one exists. Rails also provides several ways to more precisely assign specific layouts to individual controllers and actions. - -h6. Specifying Layouts on a per-Controller Basis - -You can override the automatic layout conventions in your controllers by using the +layout+ declaration in the controller. For example: - - -class ProductsController < ApplicationController - layout "inventory" - #... -end - - -With this declaration, all methods within +ProductsController+ will use +app/views/layouts/inventory.html.erb+ for their layout. - -To assign a specific layout for the entire application, use a declaration in your +ApplicationController+ class: - - -class ApplicationController < ActionController::Base - layout "main" - #... -end - - -With this declaration, all views in the entire application will use +app/views/layouts/main.html.erb+ for their layout. - -h6. Choosing Layouts at Runtime - -You can use a symbol to defer the choice of layout until a request is processed: - - -class ProductsController < ApplicationController - layout :products_layout - - def show - @product = Product.find(params[:id]) - end - - private - def products_layout - @current_user.special? ? "special" : "products" - end - -end - - -Now, if the current user is a special user, they'll get a special layout when viewing a product. You can even use an inline method to determine the layout: - - -class ProductsController < ApplicationController - layout proc { |controller| controller.request.xhr? ? 'popup' : 'application' } - # ... -end - - -h6. Conditional Layouts - -Layouts specified at the controller level support +:only+ and +:except+ options that take either a method name or an array of method names: - - -class ProductsController < ApplicationController - layout "product", :except => [:index, :rss] - #... -end - - -With this declaration, the +product+ layout would be used for everything but the +rss+ and +index+ methods. - -h6. Layout Inheritance - -Layouts are shared downwards in the hierarchy, and more specific layouts always override more general ones. For example: - -* +application_controller.rb+ - - -class ApplicationController < ActionController::Base - layout "main" - #... -end - - -* +posts_controller.rb+ - - -class PostsController < ApplicationController - # ... -end - - -* +special_posts_controller.rb+ - - -class SpecialPostsController < PostsController - layout "special" - # ... -end - - -* +old_posts_controller.rb+ - - -class OldPostsController < SpecialPostsController - layout nil - - def show - @post = Post.find(params[:id]) - end - - def index - @old_posts = Post.older - render :layout => "old" - end - # ... -end - - -In this application: - -* In general, views will be rendered in the +main+ layout -* +PostsController#index+ will use the +main+ layout -* +SpecialPostsController#index+ will use the +special+ layout -* +OldPostsController#show+ will use no layout at all -* +OldPostsController#index+ will use the +old+ layout - -h5. Avoiding Double Render Errors - -Sooner or later, most Rails developers will see the error message "Can only render or redirect once per action". While this is annoying, it's relatively easy to fix. Usually it happens because of a fundamental misunderstanding of the way that +render+ works. - -For example, here's some code that will trigger this error: - - -def show - @book = Book.find(params[:id]) - if @book.special? - render :action => "special_show" - end - render :action => "regular_show" -end - - -If +@book.special?+ evaluates to +true+, Rails will start the rendering process to dump the +@book+ variable into the +special_show+ view. But this will _not_ stop the rest of the code in the +show+ action from running, and when Rails hits the end of the action, it will start to render the +show+ view - and throw an error. The solution is simple: make sure that you only have one call to +render+ or +redirect+ in a single code path. One thing that can help is +and return+. Here's a patched version of the method: - - -def show - @book = Book.find(params[:id]) - if @book.special? - render :action => "special_show" and return - end - render :action => "regular_show" -end - - -Note that the implicit render done by ActionController detects if +render+ has been called, and thus avoids this error. So this code will work with problems: - - - def show - @book = Book.find(params[:id]) - if @book.special? - render :action => "special_show" - end - end - - -This will render a book with +special?+ set with the +special_show+ template, while other books will render with the default +show+ template. - -h4. Using +redirect_to+ - -Another way to handle returning responses to an HTTP request is with +redirect_to+. As you've seen, +render+ tells Rails which view (or other asset) to use in constructing a response. The +redirect_to+ method does something completely different: it tells the browser to send a new request for a different URL. For example, you could redirect from wherever you are in your code to the index of photos in your application with this call: - - -redirect_to photos_path - - -You can use +redirect_to+ with any arguments that you could use with +link_to+ or +url_for+. In addition, there's a special redirect that sends the user back to the page they just came from: - - -redirect_to :back - - -h5. Getting a Different Redirect Status Code - -Rails uses HTTP status code 302 (permanent redirect) when you call +redirect_to+. If you'd like to use a different status code (perhaps 301, temporary redirect), you can do so by using the +:status+ option: - - -redirect_to photos_path, :status => 301 - - -Just like the +:status+ option for +render+, +:status+ for +redirect_to+ accepts both numeric and symbolic header designations. - -h5. The Difference Between +render+ and +redirect_to+ - -Sometimes inexperienced developers conceive of +redirect_to+ as a sort of +goto+ command, moving execution from one place to another in your Rails code. This is _not_ correct. Your code stops running and waits for a new request for the browser. It just happens that you've told the browser what request it should make next, by sending back an HTTP 302 status code. - -Consider these actions to see the difference: - - -def index - @books = Book.find(:all) -end - -def show - @book = Book.find(params[:id]) - if @book.nil? - render :action => "index" - end -end - - -With the code in this form, there will be likely be a problem if the +@book+ variable is +nil+. Remember, a +render :action+ doesn't run any code in the target action, so nothing will set up the +@books+ variable that the +index+ view is presumably depending on. One way to fix this is to redirect instead of rendering: - - -def index - @books = Book.find(:all) -end - -def show - @book = Book.find(params[:id]) - if @book.nil? - redirect_to :action => "index" - end -end - - -With this code, the browser will make a fresh request for the index page, the code in the +index+ method will run, and all will be well. - -h4. Using +head+ To Build Header-Only Responses - -The +head+ method exists to let you send back responses to the browser that have only headers. It provides a more obvious alternative to calling +render :nothing+. The +head+ method takes one response, which is interpreted as a hash of header names and values. For example, you can return only an error header: - - -head :bad_request - - -Or you can use other HTTP headers to convey additional information: - - -head :created, :location => photo_path(@photo) - - -h3. Structuring Layouts - -When Rails renders a view as a response, it does so by combining the view with the current layout (using the rules for finding the current layout that were covered earlier in this guide). Within a layout, you have access to three tools for combining different bits of output to form the overall response: - -* Asset tags -* +yield+ and +content_for+ -* Partials - -I'll discuss each of these in turn. - -h4. Asset Tags - -Asset tags provide methods for generating HTML that links views to assets like images, javascript, stylesheets, and feeds. There are four types of include tag: - -* auto_discovery_link_tag -* javascript_include_tag -* stylesheet_link_tag -* image_tag - -You can use these tags in layouts or other views, although the tags other than +image_tag+ are most commonly used in the +<head>+ section of a layout. - -WARNING: The asset tags do _not_ verify the existence of the assets at the specified locations; they simply assume that you know what you're doing and generate the link. - -h5. Linking to Feeds with +auto_discovery_link_tag+ - -The +auto_discovery_link_tag+ helper builds HTML that most browsers and newsreaders can use to detect the presences of RSS or ATOM feeds. It takes the type of the link (+:rss+ or +:atom+), a hash of options that are passed through to url_for, and a hash of options for the tag: - -Hello, Rails!
-Hello, Rails!
- - -Here are a few of our fine products:
-... - -<%= render :partial => "shared/footer" %> -
- Zone name
- <%= f.text_field :name %>
-
- <%= f.submit button_label %> -
-<% end %> -Product Name: <%= product.name %>
-Product Name: <%= product.name %>
-Name: <%= customer.name %>
-Name: <%= employee.name %>
--gem install rails -rails yaffle_guide -cd yaffle_guide -script/generate scaffold bird name:string -rake db:migrate -script/server -- -Then navigate to http://localhost:3000/birds. Make sure you have a functioning rails app before continuing. - -NOTE: The aforementioned instructions will work for sqlite3. For more detailed instructions on how to create a rails app for other databases see the API docs. - - -h4. Generate the Plugin Skeleton - -Rails ships with a plugin generator which creates a basic plugin skeleton. Pass the plugin name, either 'CamelCased' or 'under_scored', as an argument. Pass +--with-generator+ to add an example generator also. - -This creates a plugin in 'vendor/plugins' including an 'init.rb' and 'README' as well as standard 'lib', 'task', and 'test' directories. - -Examples: -
-./script/generate plugin yaffle -./script/generate plugin yaffle --with-generator -- -To get more detailed help on the plugin generator, type +./script/generate plugin+. - -Later on this guide will describe how to work with generators, so go ahead and generate your plugin with the +--with-generator+ option now: - -
-./script/generate plugin yaffle --with-generator -- -You should see the following output: - -
-create vendor/plugins/yaffle/lib -create vendor/plugins/yaffle/tasks -create vendor/plugins/yaffle/test -create vendor/plugins/yaffle/README -create vendor/plugins/yaffle/MIT-LICENSE -create vendor/plugins/yaffle/Rakefile -create vendor/plugins/yaffle/init.rb -create vendor/plugins/yaffle/install.rb -create vendor/plugins/yaffle/uninstall.rb -create vendor/plugins/yaffle/lib/yaffle.rb -create vendor/plugins/yaffle/tasks/yaffle_tasks.rake -create vendor/plugins/yaffle/test/core_ext_test.rb -create vendor/plugins/yaffle/generators -create vendor/plugins/yaffle/generators/yaffle -create vendor/plugins/yaffle/generators/yaffle/templates -create vendor/plugins/yaffle/generators/yaffle/yaffle_generator.rb -create vendor/plugins/yaffle/generators/yaffle/USAGE -- -h4. Organize Your Files - -To make it easy to organize your files and to make the plugin more compatible with GemPlugins, start out by altering your file system to look like this: - -
-|-- lib -| |-- yaffle -| `-- yaffle.rb -`-- rails - | - `-- init.rb -- -*vendor/plugins/yaffle/rails/init.rb* - - -require 'yaffle' - - -Now you can add any 'require' statements to 'lib/yaffle.rb' and keep 'init.rb' clean. - -h3. Tests - -In this guide you will learn how to test your plugin against multiple different database adapters using Active Record. To setup your plugin to allow for easy testing you'll need to add 3 files: - - * A 'database.yml' file with all of your connection strings - * A 'schema.rb' file with your table definitions - * A test helper method that sets up the database - -h4. Test Setup - -*vendor/plugins/yaffle/test/database.yml:* - -
-sqlite: - :adapter: sqlite - :dbfile: vendor/plugins/yaffle/test/yaffle_plugin.sqlite.db - -sqlite3: - :adapter: sqlite3 - :dbfile: vendor/plugins/yaffle/test/yaffle_plugin.sqlite3.db - -postgresql: - :adapter: postgresql - :username: postgres - :password: postgres - :database: yaffle_plugin_test - :min_messages: ERROR - -mysql: - :adapter: mysql - :host: localhost - :username: root - :password: password - :database: yaffle_plugin_test -- -For this guide you'll need 2 tables/models, Hickwalls and Wickwalls, so add the following: - -*vendor/plugins/yaffle/test/schema.rb:* - - -ActiveRecord::Schema.define(:version => 0) do - create_table :hickwalls, :force => true do |t| - t.string :name - t.string :last_squawk - t.datetime :last_squawked_at - end - create_table :wickwalls, :force => true do |t| - t.string :name - t.string :last_tweet - t.datetime :last_tweeted_at - end - create_table :woodpeckers, :force => true do |t| - t.string :name - end -end - - -*vendor/plugins/yaffle/test/test_helper.rb:* - - -ENV['RAILS_ENV'] = 'test' -ENV['RAILS_ROOT'] ||= File.dirname(__FILE__) + '/../../../..' - -require 'test/unit' -require File.expand_path(File.join(ENV['RAILS_ROOT'], 'config/environment.rb')) - -def load_schema - config = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml')) - ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + "/debug.log") - - db_adapter = ENV['DB'] - - # no db passed, try one of these fine config-free DBs before bombing. - db_adapter ||= - begin - require 'rubygems' - require 'sqlite' - 'sqlite' - rescue MissingSourceFile - begin - require 'sqlite3' - 'sqlite3' - rescue MissingSourceFile - end - end - - if db_adapter.nil? - raise "No DB Adapter selected. Pass the DB= option to pick one, or install Sqlite or Sqlite3." - end - - ActiveRecord::Base.establish_connection(config[db_adapter]) - load(File.dirname(__FILE__) + "/schema.rb") - require File.dirname(__FILE__) + '/../rails/init.rb' -end - - -Now whenever you write a test that requires the database, you can call 'load_schema'. - -h4. Run the Plugin Tests - -Once you have these files in place, you can write your first test to ensure that your plugin-testing setup is correct. By default rails generates a file in 'vendor/plugins/yaffle/test/yaffle_test.rb' with a sample test. Replace the contents of that file with: - -*vendor/plugins/yaffle/test/yaffle_test.rb:* - - -require File.dirname(__FILE__) + '/test_helper.rb' - -class YaffleTest < Test::Unit::TestCase - load_schema - - class Hickwall < ActiveRecord::Base - end - - class Wickwall < ActiveRecord::Base - end - - def test_schema_has_loaded_correctly - assert_equal [], Hickwall.all - assert_equal [], Wickwall.all - end - -end - - -To run this, go to the plugin directory and run +rake+: - -
-cd vendor/plugins/yaffle -rake -- -You should see output like: - -
-GET /patients/17 -- -the routing engine within Rails is the piece of code that dispatches the request to the appropriate spot in your application. In this case, the application would most likely end up running the +show+ action within the +patients+ controller, displaying the details of the patient whose ID is 17. - -h4. Generating URLs from Code - -Routing also works in reverse. If your application contains this code: - - -@patient = Patient.find(17) - - -
-DELETE /photos/17 -- -would be understood to refer to a photo resource with the ID of 17, and to indicate a desired action - deleting that resource. REST is a natural style for the architecture of web applications, and Rails makes it even more natural by using conventions to shield you from some of the RESTful complexities. - -h4. CRUD, Verbs, and Actions - -In Rails, a RESTful route provides a mapping between HTTP verbs, controller actions, and (implicitly) CRUD operations in a database. A single entry in the routing file, such as - - -map.resources :photos - - -creates seven different routes in your application: - -|_.HTTP verb|_.URL |_.controller|_.action |_.used for| -|GET |/photos |Photos |index |display a list of all photos| -|GET |/photos/new |Photos |new |return an HTML form for creating a new photo| -|POST |/photos |Photos |create |create a new photo| -|GET |/photos/1 |Photos |show |display a specific photo| -|GET |/photos/1/edit |Photos |edit |return an HTML form for editing a photo| -|PUT |/photos/1 |Photos |update |update a specific photo| -|DELETE |/photos/1 |Photos |destroy |delete a specific photo| - -For the specific routes (those that reference just a single resource), the identifier for the resource will be available within the corresponding controller action as +params[:id]+. - -TIP: If you consistently use RESTful routes in your application, you should disable the default routes in +routes.rb+ so that Rails will enforce the mapping between HTTP verbs and routes. - -h4. URLs and Paths - -Creating a RESTful route will also make available a pile of helpers within your application: - -* +photos_url+ and +photos_path+ map to the path for the index and create actions -* +new_photo_url+ and +new_photo_path+ map to the path for the new action -* +edit_photo_url+ and +edit_photo_path+ map to the path for the edit action -* +photo_url+ and +photo_path+ map to the path for the show, update, and destroy actions - -NOTE: Because routing makes use of the HTTP verb as well as the path in the request to dispatch requests, the seven routes generated by a RESTful routing entry only give rise to four pairs of helpers. - -In each case, the +_url+ helper generates a string containing the entire URL that the application will understand, while the +_path+ helper generates a string containing the relative path from the root of the application. For example: - - -photos_url # => "http://www.example.com/photos" -photos_path # => "/photos" - - -h4. Defining Multiple Resources at the Same Time - -If you need to create routes for more than one RESTful resource, you can save a bit of typing by defining them all with a single call to +map.resources+: - - -map.resources :photos, :books, :videos - - -This has exactly the same effect as - - -map.resources :photos -map.resources :books -map.resources :videos - - -h4. Singular Resources - -You can also apply RESTful routing to singleton resources within your application. In this case, you use +map.resource+ instead of +map.resources+ and the route generation is slightly different. For example, a routing entry of - - -map.resource :geocoder - - -creates six different routes in your application: - -|_.HTTP verb|_.URL |_.controller|_.action |_.used for| -|GET |/geocoder/new |Geocoders |new |return an HTML form for creating the new geocoder| -|POST |/geocoder |Geocoders |create |create the new geocoder| -|GET |/geocoder |Geocoders |show |display the one and only geocoder resource| -|GET |/geocoder/edit |Geocoders |edit |return an HTML form for editing the geocoder| -|PUT |/geocoder |Geocoders |update |update the one and only geocoder resource| -|DELETE |/geocoder |Geocoders |destroy |delete the geocoder resource| - -NOTE: Even though the name of the resource is singular in +routes.rb+, the matching controller is still plural. - -A singular RESTful route generates an abbreviated set of helpers: - -* +new_geocoder_url+ and +new_geocoder_path+ map to the path for the new action -* +edit_geocoder_url+ and +edit_geocoder_path+ map to the path for the edit action -* +geocoder_url+ and +geocoder_path+ map to the path for the create, show, update, and destroy actions - -h4. Customizing Resources - -Although the conventions of RESTful routing are likely to be sufficient for many applications, there are a number of ways to customize the way that RESTful routes work. These options include: - -* +:controller+ -* +:singular+ -* +:requirements+ -* +:conditions+ -* +:as+ -* +:path_names+ -* +:path_prefix+ -* +:name_prefix+ -* +:only+ -* +:except+ - -You can also add additional routes via the +:member+ and +:collection+ options, which are discussed later in this guide. - -h5. Using +:controller+ - -The +:controller+ option lets you use a controller name that is different from the public-facing resource name. For example, this routing entry: - - -map.resources :photos, :controller => "images" - - -will recognize incoming URLs containing +photo+ but route the requests to the Images controller: - -|_.HTTP verb|_.URL |_.controller|_.action |_.used for| -|GET |/photos |Images |index |display a list of all images| -|GET |/photos/new |Images |new |return an HTML form for creating a new image| -|POST |/photos |Images |create |create a new image| -|GET |/photos/1 |Images |show |display a specific image| -|GET |/photos/1/edit |Images |edit |return an HTML form for editing a image| -|PUT |/photos/1 |Images |update |update a specific image| -|DELETE |/photos/1 |Images |destroy |delete a specific image| - -NOTE: The helpers will be generated with the name of the resource, not the name of the controller. So in this case, you'd still get +photos_path+, +new_photo_path+, and so on. - -h4. Controller Namespaces and Routing - -Rails allows you to group your controllers into namespaces by saving them in folders underneath +app/controllers+. The +:controller+ option provides a convenient way to use these routes. For example, you might have a resource whose controller is purely for admin users in the +admin+ folder: - - -map.resources :adminphotos, :controller => "admin/photos" - - -If you use controller namespaces, you need to be aware of a subtlety in the Rails routing code: it always tries to preserve as much of the namespace from the previous request as possible. For example, if you are on a view generated from the +adminphoto_path+ helper, and you follow a link generated with +<%= link_to "show", adminphoto(1) %>+ you will end up on the view generated by +admin/photos/show+, but you will also end up in the same place if you have +<%= link_to "show", {:controller => "photos", :action => "show"} %>+ because Rails will generate the show URL relative to the current URL. - -TIP: If you want to guarantee that a link goes to a top-level controller, use a preceding slash to anchor the controller name: +<%= link_to "show", {:controller => "/photos", :action => "show"} %>+ - -You can also specify a controller namespace with the +:namespace+ option instead of a path: - - -map.resources :adminphotos, :namespace => "admin", :controller => "photos" - - -This can be especially useful when combined with +with_options+ to map multiple namespaced routes together: - - -map.with_options(:namespace => "admin") do |admin| - admin.resources :photos, :videos -end - - -That would give you routing for +admin/photos+ and +admin/videos+ controllers. - -h5. Using +:singular+ - -If for some reason Rails isn't doing what you want in converting the plural resource name to a singular name in member routes, you can override its judgment with the +:singular+ option: - - -map.resources :teeth, :singular => "tooth" - - -TIP: Depending on the other code in your application, you may prefer to add additional rules to the +Inflector+ class instead. - -h5. Using +:requirements+ - -You can use the +:requirements+ option in a RESTful route to impose a format on the implied +:id+ parameter in the singular routes. For example: - - -map.resources :photos, :requirements => {:id => /[A-Z][A-Z][0-9]+/} - - -This declaration constrains the +:id+ parameter to match the supplied regular expression. So, in this case, +/photos/1+ would no longer be recognized by this route, but +/photos/RR27+ would. - -h5. Using +:conditions+ - -Conditions in Rails routing are currently used only to set the HTTP verb for individual routes. Although in theory you can set this for RESTful routes, in practice there is no good reason to do so. (You'll learn more about conditions in the discussion of classic routing later in this guide.) - -h5. Using +:as+ - -The +:as+ option lets you override the normal naming for the actual generated paths. For example: - - -map.resources :photos, :as => "images" - - -will recognize incoming URLs containing +image+ but route the requests to the Photos controller: - -|_.HTTP verb|_.URL |_.controller|_.action |_:used for| -|GET |/images |Photos |index |display a list of all photos| -|GET |/images/new |Photos |new |return an HTML form for creating a new photo| -|POST |/images |Photos |create |create a new photo| -|GET |/images/1 |Photos |show |display a specific photo| -|GET |/images/1/edit |Photos |edit |return an HTML form for editing a photo| -|PUT |/images/1 |Photos |update |update a specific photo| -|DELETE |/images/1 |Photos |destroy |delete a specific photo| - -NOTE: The helpers will be generated with the name of the resource, not the path name. So in this case, you'd still get +photos_path+, +new_photo_path+, and so on. - -h5. Using +:path_names+ - -The +:path_names+ option lets you override the automatically-generated "new" and "edit" segments in URLs: - - -map.resources :photos, :path_names => { :new => 'make', :edit => 'change' } - - -This would cause the routing to recognize URLs such as - -
-/photos/make -/photos/1/change -- -NOTE: The actual action names aren't changed by this option; the two URLs shown would still route to the new and edit actions. - -TIP: If you find yourself wanting to change this option uniformly for all of your routes, you can set a default in your environment: - - -config.action_controller.resources_path_names = { :new => 'make', :edit => 'change' } - - -h5. Using +:path_prefix+ - -The +:path_prefix+ option lets you add additional parameters that will be prefixed to the recognized paths. For example, suppose each photo in your application belongs to a particular photographer. In that case, you might declare this route: - - -map.resources :photos, :path_prefix => '/photographers/:photographer_id' - - -Routes recognized by this entry would include: - -
-/photographers/1/photos/2 -/photographers/1/photos -- -NOTE: In most cases, it's simpler to recognize URLs of this sort by creating nested resources, as discussed in the next section. - -NOTE: You can also use +:path_prefix+ with non-RESTful routes. - -h5. Using +:name_prefix+ - -You can use the :name_prefix option to avoid collisions between routes. This is most useful when you have two resources with the same name that use +:path_prefix+ to map differently. For example: - - -map.resources :photos, :path_prefix => '/photographers/:photographer_id', - :name_prefix => 'photographer_' -map.resources :photos, :path_prefix => '/agencies/:agency_id', - :name_prefix => 'agency_' - - -This combination will give you route helpers such as +photographer_photos_path+ and +agency_edit_photo_path+ to use in your code. - -NOTE: You can also use +:name_prefix+ with non-RESTful routes. - -h5. Using +:only+ and +:except+ - -By default, Rails creates routes for all seven of the default actions (index, show, new, create, edit, update, and destroy) for every RESTful route in your application. You can use the +:only+ and +:except+ options to fine-tune this behavior. The +:only+ option specifies that only certain routes should be generated: - - -map.resources :photos, :only => [:index, :show] - - -With this declaration, a +GET+ request to +/photos+ would succeed, but a +POST+ request to +/photos+ (which would ordinarily be routed to the create action) will fail. - -The +:except+ option specifies a route or list of routes that should _not_ be generated: - - -map.resources :photos, :except => :destroy - - -In this case, all of the normal routes except the route for +destroy+ (a +DELETE+ request to +/photos/id+) will be generated. - -In addition to an action or a list of actions, you can also supply the special symbols +:all+ or +:none+ to the +:only+ and +:except+ options. - -TIP: If your application has many RESTful routes, using +:only+ and +:except+ to generate only the routes that you actually need can cut down on memory use and speed up the routing process. - -h4. Nested Resources - -It's common to have resources that are logically children of other resources. For example, suppose your application includes these models: - - -class Magazine < ActiveRecord::Base - has_many :ads -end - -class Ad < ActiveRecord::Base - belongs_to :magazine -end - - -Each ad is logically subservient to one magazine. Nested routes allow you to capture this relationship in your routing. In this case, you might include this route declaration: - - -map.resources :magazines do |magazine| - magazine.resources :ads -end - - -TIP: Further below you'll learn about a convenient shortcut for this construct:
-/publishers/1/magazines/2/photos/3 -- -The corresponding route helper would be +publisher_magazine_photo_url+, requiring you to specify objects at all three levels. Indeed, this situation is confusing enough that a popular "article":http://weblog.jamisbuck.org/2007/2/5/nesting-resources by Jamis Buck proposes a rule of thumb for good Rails design: - -TIP: _Resources should never be nested more than 1 level deep._ - -h5. Shallow Nesting - -The +:shallow+ option provides an elegant solution to the difficulties of deeply-nested routes. If you specify this option at any level of routing, then paths for nested resources which reference a specific member (that is, those with an +:id+ parameter) will not use the parent path prefix or name prefix. To see what this means, consider this set of routes: - - -map.resources :publishers, :shallow => true do |publisher| - publisher.resources :magazines do |magazine| - magazine.resources :photos - end -end - - -This will enable recognition of (among others) these routes: - -
-/publishers/1 ==> publisher_path(1) -/publishers/1/magazines ==> publisher_magazines_path(1) -/magazines/2 ==> magazine_path(2) -/magazines/2/photos ==> magazines_photos_path(2) -/photos/3 ==> photo_path(3) -- -With shallow nesting, you need only supply enough information to uniquely identify the resource that you want to work with. If you like, you can combine shallow nesting with the +:has_one+ and +:has_many+ options: - - -map.resources :publishers, :has_many => { :magazines => :photos }, :shallow => true - - -h4. Route Generation from Arrays - -In addition to using the generated routing helpers, Rails can also generate RESTful routes from an array of parameters. For example, suppose you have a set of routes generated with these entries in routes.rb: - - -map.resources :magazines do |magazine| - magazine.resources :ads -end - - -Rails will generate helpers such as magazine_ad_path that you can use in building links: - - -<%= link_to "Ad details", magazine_ad_path(@magazine, @ad) %> - - -Another way to refer to the same route is with an array of objects: - - -<%= link_to "Ad details", [@magazine, @ad] %> - - -This format is especially useful when you might not know until runtime which of several types of object will be used in a particular link. - -h4. Namespaced Resources - -It's possible to do some quite complex things by combining +:path_prefix+ and +:name_prefix+. For example, you can use the combination of these two options to move administrative resources to their own folder in your application: - - -map.resources :photos, :path_prefix => 'admin', :controller => 'admin/photos' -map.resources :tags, :name_prefix => 'admin_photo_', :path_prefix => 'admin/photos/:photo_id', :controller => 'admin/photo_tags' -map.resources :ratings, :name_prefix => 'admin_photo_', :path_prefix => 'admin/photos/:photo_id', :controller => 'admin/photo_ratings' - - -The good news is that if you find yourself using this level of complexity, you can stop. Rails supports _namespaced resources_ to make placing resources in their own folder a snap. Here's the namespaced version of those same three routes: - - -map.namespace(:admin) do |admin| - admin.resources :photos, - :has_many => { :tags, :ratings} -end - - -As you can see, the namespaced version is much more succinct than the one that spells everything out - but it still creates the same routes. For example, you'll get +admin_photos_url+ that expects to find an +Admin::PhotosController+ and that matches +admin/photos+, and +admin_photos_ratings_path+ that matches +/admin/photos/_photo_id_/ratings+, expecting to use +Admin::RatingsController+. Even though you're not specifying +path_prefix+ explicitly, the routing code will calculate the appropriate +path_prefix+ from the route nesting. - -h4. Adding More RESTful Actions - -You are not limited to the seven routes that RESTful routing creates by default. If you like, you may add additional member routes (those which apply to a single instance of the resource), additional new routes (those that apply to creating a new resource), or additional collection routes (those which apply to the collection of resources as a whole). - -h5. Adding Member Routes - -To add a member route, use the +:member+ option: - - -map.resources :photos, :member => { :preview => :get } - - -This will enable Rails to recognize URLs such as +/photos/1/preview+ using the GET HTTP verb, and route them to the preview action of the Photos controller. It will also create a +preview_photo+ route helper. - -Within the hash of member routes, each route name specifies the HTTP verb that it will recognize. You can use +:get+, +:put+, +:post+, +:delete+, or +:any+ here. You can also specify an array of methods, if you need more than one but you don't want to allow just anything: - - -map.resources :photos, :member => { :prepare => [:get, :post] } - - -h5. Adding Collection Routes - -To add a collection route, use the +:collection+ option: - - -map.resources :photos, :collection => { :search => :get } - - -This will enable Rails to recognize URLs such as +/photos/search+ using the GET HTTP verb, and route them to the search action of the Photos controller. It will also create a +search_photos+ route helper. - -Just as with member routes, you can specify an array of methods for a collection route: - - -map.resources :photos, :collection => { :search => [:get, :post] } - - -h5. Adding New Routes - -To add a new route (one that creates a new resource), use the +:new+ option: - - -map.resources :photos, :new => { :upload => :post } - - -This will enable Rails to recognize URLs such as +/photos/upload+ using the POST HTTP verb, and route them to the upload action of the Photos controller. It will also create a +upload_photos+ route helper. - -TIP: If you want to redefine the verbs accepted by one of the standard actions, you can do so by explicitly mapping that action. For example:
- users GET /users {:controller=>"users", :action=>"index"}
-formatted_users GET /users.:format {:controller=>"users", :action=>"index"}
- POST /users {:controller=>"users", :action=>"create"}
- POST /users.:format {:controller=>"users", :action=>"create"}
-
-
-TIP: You'll find that the output from +rake routes+ is much more readable if you widen your terminal window until the output lines don't wrap.
-
-h4. Testing Routes
-
-Routes should be included in your testing strategy (just like the rest of your application). Rails offers three "built-in assertions":http://api.rubyonrails.org/classes/ActionController/Assertions/RoutingAssertions.html designed to make testing routes simpler:
-
-* +assert_generates+
-* +assert_recognizes+
-* +assert_routing+
-
-h5. The +assert_generates+ Assertion
-
-Use +assert_generates+ to assert that a particular set of options generate a particular path. You can use this with default routes or custom routes
-
-
-assert_generates "/photos/1", { :controller => "photos", :action => "show", :id => "1" }
-assert_generates "/about", :controller => "pages", :action => "about"
-
-
-h5. The +assert_recognizes+ Assertion
-
-The +assert_recognizes+ assertion is the inverse of +assert_generates+. It asserts that Rails recognizes the given path and routes it to a particular spot in your application.
-
-
-assert_recognizes { :controller => "photos", :action => "show", :id => "1" }, "/photos/1"
-
-
-You can supply a +:method+ argument to specify the HTTP verb:
-
-
-assert_recognizes { :controller => "photos", :action => "create" }, { :path => "photos", :method => :post }
-
-
-You can also use the RESTful helpers to test recognition of a RESTful route:
-
-
-assert_recognizes new_photo_url, { :path => "photos", :method => :post }
-
-
-h5. The +assert_routing+ Assertion
-
-The +assert_routing+ assertion checks the route both ways: it tests that the path generates the options, and that the options generate the path. Thus, it combines the functions of +assert_generates+ and +assert_recognizes+.
-
-
-assert_routing { :path => "photos", :method => :post }, { :controller => "photos", :action => "create" }
-
-
-h3. Changelog
-
-"Lighthouse ticket":http://rails.lighthouseapp.com/projects/16213-rails-guides/tickets/3
-
-* October 4, 2008: Added additional detail on specifying verbs for resource member/collection routes, by "Mike Gunderloy":credits.html#mgunderloy
-* September 23, 2008: Added section on namespaced controllers and routing, by "Mike Gunderloy":credits.html#mgunderloy
-* September 10, 2008: initial version by "Mike Gunderloy":credits.html#mgunderloy
diff --git a/vendor/rails/railties/guides/source/security.textile b/vendor/rails/railties/guides/source/security.textile
deleted file mode 100644
index 1b64cc1b..00000000
--- a/vendor/rails/railties/guides/source/security.textile
+++ /dev/null
@@ -1,986 +0,0 @@
-h2. Ruby On Rails Security Guide
-
-This manual describes common security problems in web applications and how to avoid them with Rails. If you have any questions or suggestions, please
-mail me, Heiko Webers, at 42 {_et_} rorsecurity.info. After reading it, you should be familiar with:
-
-* All countermeasures _(highlight)that are highlighted_
-* The concept of sessions in Rails, what to put in there and popular attack methods
-* How just visiting a site can be a security problem (with CSRF)
-* What you have to pay attention to when working with files or providing an administration interface
-* The Rails-specific mass assignment problem
-* How to manage users: Logging in and out and attack methods on all layers
-* And the most popular injection attack methods
-
-endprologue.
-
-h3. Introduction
-
-Web application frameworks are made to help developers building web applications. Some of them also help you with securing the web application. In fact one framework is not more secure than another: If you use it correctly, you will be able to build secure apps with many frameworks. Ruby on Rails has some clever helper methods, for example against SQL injection, so that this is hardly a problem. It‘s nice to see that all of the Rails applications I audited had a good level of security.
-
-In general there is no such thing as plug-n-play security. Security depends on the people using the framework, and sometimes on the development method. And it depends on all layers of a web application environment: The back-end storage, the web server and the web application itself (and possibly other layers or applications).
-
-The Gartner Group however estimates that 75% of attacks are at the web application layer, and found out "that out of 300 audited sites, 97% are vulnerable to attack". This is because web applications are relatively easy to attack, as they are simple to understand and manipulate, even by the lay person.
-
-The threats against web applications include user account hijacking, bypass of access control, reading or modifying sensitive data, or presenting fraudulent content. Or an attacker might be able to install a Trojan horse program or unsolicited e-mail sending software, aim at financial enrichment or cause brand name damage by modifying company resources. In order to prevent attacks, minimize their impact and remove points of attack, first of all, you have to fully understand the attack methods in order to find the correct countermeasures. That is what this guide aims at.
-
-In order to develop secure web applications you have to keep up to date on all layers and know your enemies. To keep up to date subscribe to security mailing lists, read security blogs and make updating and security checks a habit (check the Additional Resources chapter). I do it manually because that‘s how you find the nasty logical security problems.
-
-h3. Sessions
-
-A good place to start looking at security is with sessions, which can be vulnerable to particular attacks.
-
-h4. What are Sessions?
-
--- _HTTP is a stateless protocol. Sessions make it stateful._
-
-Most applications need to keep track of certain state of a particular user. This could be the contents of a shopping basket or the user id of the currently logged in user. Without the idea of sessions, the user would have to identify, and probably authenticate, on every request.
-Rails will create a new session automatically if a new user accesses the application. It will load an existing session if the user has already used the application.
-
-A session usually consists of a hash of values and a session id, usually a 32-character string, to identify the hash. Every cookie sent to the client's browser includes the session id. And the other way round: the browser will send it to the server on every request from the client. In Rails you can save and retrieve values using the session method:
-
-
-session[:user_id] = @current_user.id
-User.find(session[:user_id])
-
-
-h4. Session id
-
--- _The session id is a 32 byte long MD5 hash value._
-
-A session id consists of the hash value of a random string. The random string is the current time, a random number between 0 and 1, the process id number of the Ruby interpreter (also basically a random number) and a constant string. Currently it is not feasible to brute-force Rails' session ids. To date MD5 is uncompromised, but there have been collisions, so it is theoretically possible to create another input text with the same hash value. But this has had no security impact to date.
-
-h4. Session Hijacking
-
--- _Stealing a user's session id lets an attacker use the web application in the victim's name._
-
-Many web applications have an authentication system: a user provides a user name and password, the web application checks them and stores the corresponding user id in the session hash. From now on, the session is valid. On every request the application will load the user, identified by the user id in the session, without the need for new authentication. The session id in the cookie identifies the session.
-
-Hence, the cookie serves as temporary authentication for the web application. Everyone who seizes a cookie from someone else, may use the web application as this user – with possibly severe consequences. Here are some ways to hijack a session, and their countermeasures:
-
-* Sniff the cookie in an insecure network. A wireless LAN can be an example of such a network. In an unencrypted wireless LAN it is especially easy to listen to the traffic of all connected clients. This is one more reason not to work from a coffee shop. For the web application builder this means to _(highlight)provide a secure connection over SSL_.
-
-* Most people don't clear out the cookies after working at a public terminal. So if the last user didn't log out of a web application, you would be able to use it as this user. Provide the user with a _(highlight)log-out button_ in the web application, and _(highlight)make it prominent_.
-
-* Many cross-site scripting (XSS) exploits aim at obtaining the user's cookie. You'll read more about XSS later.
-
-* Instead of stealing a cookie unknown to the attacker, he fixes a user's session identifier (in the cookie) known to him. Read more about this so-called session fixation later.
-
-The main objective of most attackers is to make money. The underground prices for stolen bank login accounts range from $10–$1000 (depending on the available amount of funds), $0.40–$20 for credit card numbers, $1–$8 for online auction site accounts and $4–$30 for email passwords, according to the "Symantec Global Internet Security Threat Report":http://eval.symantec.com/mktginfo/enterprise/white_papers/b-whitepaper_internet_security_threat_report_xiii_04-2008.en-us.pdf.
-
-h4. Session Guidelines
-
--- _Here are some general guidelines on sessions._
-
-* _(highlight)Do not store large objects in a session_. Instead you should store them in the database and save their id in the session. This will eliminate synchronization headaches and it won't fill up your session storage space (depending on what session storage you chose, see below).
-This will also be a good idea, if you modify the structure of an object and old versions of it are still in some user's cookies. With server-side session storages you can clear out the sessions, but with client-side storages, this is hard to mitigate.
-
-* _(highlight)Critical data should not be stored in session_. If the user clears his cookies or closes the browser, they will be lost. And with a client-side session storage, the user can read the data.
-
-
-h4. Session Storage
-
--- _Rails provides several storage mechanisms for the session hashes. The most important are ActiveRecordStore and CookieStore._
-
-There are a number of session storages, i.e. where Rails saves the session hash and session id. Most real-live applications choose ActiveRecordStore (or one of its derivatives) over file storage due to performance and maintenance reasons. ActiveRecordStore keeps the session id and hash in a database table and saves and retrieves the hash on every request.
-
-Rails 2 introduced a new default session storage, CookieStore. CookieStore saves the session hash directly in a cookie on the client-side. The server retrieves the session hash from the cookie and eliminates the need for a session id. That will greatly increase the speed of the application, but it is a controversial storage option and you have to think about the security implications of it:
-
-* Cookies imply a strict size limit of 4kB. This is fine as you should not store large amounts of data in a session anyway, as described before. _(highlight)Storing the current user's database id in a session is usually ok_.
-
-* The client can see everything you store in a session, because it is stored in clear-text (actually Base64-encoded, so not encrypted). So, of course, _(highlight)you don't want to store any secrets here_. To prevent session hash tampering, a digest is calculated from the session with a server-side secret and inserted into the end of the cookie.
-
-That means the security of this storage depends on this secret (and on the digest algorithm, which defaults to SHA512, which has not been compromised, yet). So _(highlight)don't use a trivial secret, i.e. a word from a dictionary, or one which is shorter than 30 characters_. Put the secret in your environment.rb:
-
-
-config.action_controller.session = {
- :key => '_app_session',
- :secret => '0x0dkfj3927dkc7djdh36rkckdfzsg...'
-}
-
-
-There are, however, derivatives of CookieStore which encrypt the session hash, so the client cannot see it.
-
-h4. Replay Attacks for CookieStore Sessions
-
--- _Another sort of attack you have to be aware of when using CookieStore is the replay attack._
-
-It works like this:
-
-* A user receives credits, the amount is stored in a session (which is a bad idea anyway, but we'll do this for demonstration purposes).
-* The user buys something.
-* His new, lower credit will be stored in the session.
-* The dark side of the user forces him to take the cookie from the first step (which he copied) and replace the current cookie in the browser.
-* The user has his credit back.
-
-Including a nonce (a random value) in the session solves replay attacks. A nonce is valid only once, and the server has to keep track of all the valid nonces. It gets even more complicated if you have several application servers (mongrels). Storing nonces in a database table would defeat the entire purpose of CookieStore (avoiding accessing the database).
-
-The best _(highlight)solution against it is not to store this kind of data in a session, but in the database_. In this case store the credit in the database and the logged_in_user_id in the session.
-
-h4. Session Fixation
-
--- _Apart from stealing a user's session id, the attacker may fix a session id known to him. This is called session fixation._
-
-!images/session_fixation.png(Session fixation)!
-
-This attack focuses on fixing a user's session id known to the attacker, and forcing the user's browser into using this id. It is therefore not necessary for the attacker to steal the session id afterwards. Here is how this attack works:
-
-# The attacker creates a valid session id: He loads the login page of the web application where he wants to fix the session, and takes the session id in the cookie from the response (see number 1 and 2 in the image).
-# He possibly maintains the session. Expiring sessions, for example every 20 minutes, greatly reduces the time-frame for attack. Therefore he accesses the web application from time to time in order to keep the session alive.
-# Now the attacker will force the user's browser into using this session id (see number 3 in the image). As you may not change a cookie of another domain (because of the same origin policy), the attacker has to run a JavaScript from the domain of the target web application. Injecting the JavaScript code into the application by XSS accomplishes this attack. Here is an example: +<script>
document.cookie="_session_id=16d5b78abb28e3d6206b60f22a03c8d9";
</script>+. Read more about XSS and injection later on.
-# The attacker lures the victim to the infected page with the JavaScript code. By viewing the page, the victim's browser will change the session id to the trap session id.
-# As the new trap session is unused, the web application will require the user to authenticate.
-# From now on, the victim and the attacker will co-use the web application with the same session: The session became valid and the victim didn't notice the attack.
-
-h4. Session Fixation – Countermeasures
-
--- _One line of code will protect you from session fixation._
-
-The most effective countermeasure is to _(highlight)issue a new session identifier_ and declare the old one invalid after a successful login. That way, an attacker cannot use the fixed session identifier. This is a good countermeasure against session hijacking, as well. Here is how to create a new session in Rails:
-
-
-reset_session
-
-
-If you use the popular RestfulAuthentication plugin for user management, add reset_session to the SessionsController#create action. Note that this removes any value from the session, _(highlight)you have to transfer them to the new session_.
-
-Another countermeasure is to _(highlight)save user-specific properties in the session_, verify them every time a request comes in, and deny access, if the information does not match. Such properties could be the remote IP address or the user agent (the web browser name), though the latter is less user-specific. When saving the IP address, you have to bear in mind that there are Internet service providers or large organizations that put their users behind proxies. _(highlight)These might change over the course of a session_, so these users will not be able to use your application, or only in a limited way.
-
-h4. Session Expiry
-
--- _Sessions that never expire extend the time-frame for attacks such as cross-site reference forgery (CSRF), session hijacking and session fixation._
-
-One possibility is to set the expiry time-stamp of the cookie with the session id. However the client can edit cookies that are stored in the web browser so expiring sessions on the server is safer. Here is an example of how to _(highlight)expire sessions in a database table_. Call +Session.sweep("20m")+ to expire sessions that were used longer than 20 minutes ago.
-
-
-class Session < ActiveRecord::Base
- def self.sweep(time_ago = nil)
-
time = case time_ago
-
when /^(\d+)m$/ then Time.now - $1.to_i.minute
-
when /^(\d+)h$/ then Time.now - $1.to_i.hour
-
when /^(\d+)d$/ then Time.now - $1.to_i.day
-
else Time.now - 1.hour
-
end
-
self.delete_all "updated_at < '#{time.to_s(:db)}'"
-
end
-
end
-
-
-The section about session fixation introduced the problem of maintained sessions. An attacker maintaining a session every five minutes can keep the session alive forever, although you are expiring sessions. A simple solution for this would be to add a created_at column to the sessions table. Now you can delete sessions that were created a long time ago. Use this line in the sweep method above:
-
-
-self.delete_all "updated_at < '#{time.to_s(:db)}' OR
- created_at < '#{2.days.ago.to_s(:db)}'"
-
-
-h3. Cross-Site Request Forgery (CSRF)
-
--- _This attack method works by including malicious code or a link in a page that accesses a web application that the user is believed to have authenticated. If the session for that web application has not timed out, an attacker may execute unauthorized commands._
-
-!images/csrf.png!
-
-In the session chapter you have learned that most Rails applications use cookie-based sessions. Either they store the session id in the cookie and have a server-side session hash, or the entire session hash is on the client-side. In either case the browser will automatically send along the cookie on every request to a domain, if it can find a cookie for that domain. The controversial point is, that it will also send the cookie, if the request comes from a site of a different domain. Let's start with an example:
-
-* Bob browses a message board and views a post from a hacker where there is a crafted HTML image element. The element references a command in Bob's project management application, rather than an image file.
-* +<img src="http://www.webapp.com/project/1/destroy">+
-* Bob's session at www.webapp.com is still alive, because he didn't log out a few minutes ago.
-* By viewing the post, the browser finds an image tag. It tries to load the suspected image from www.webapp.com. As explained before, it will also send along the cookie with the valid session id.
-* The web application at www.webapp.com verifies the user information in the corresponding session hash and destroys the project with the ID 1. It then returns a result page which is an unexpected result for the browser, so it will not display the image.
-* Bob doesn't notice the attack -- but a few days later he finds out that project number one is gone.
-
-It is important to notice that the actual crafted image or link doesn't necessarily have to be situated in the web application's domain, it can be anywhere – in a forum, blog post or email.
-
-CSRF appears very rarely in CVE (Common Vulnerabilities and Exposures) -- less than 0.1% in 2006 -- but it really is a 'sleeping giant' [Grossman]. This is in stark contrast to the results in my (and others) security contract work – _(highlight)CSRF is an important security issue_.
-
-h4. CSRF Countermeasures
-
--- _First, as is required by the W3C, use GET and POST appropriately. Secondly, a security token in non-GET requests will protect your application from CSRF._
-
-The HTTP protocol basically provides two main types of requests - GET and POST (and more, but they are not supported by most browsers). The World Wide Web Consortium (W3C) provides a checklist for choosing HTTP GET or POST:
-
-*Use GET if:*
-
-* The interaction is more _(highlight)like a question_ (i.e., it is a safe operation such as a query, read operation, or lookup).
-
-*Use POST if:*
-
-* The interaction is more _(highlight)like an order_, or
-* The interaction _(highlight)changes the state_ of the resource in a way that the user would perceive (e.g., a subscription to a service), or
-* The user is _(highlight)held accountable for the results_ of the interaction.
-
-If your web application is RESTful, you might be used to additional HTTP verbs, such as PUT or DELETE. Most of today‘s web browsers, however do not support them - only GET and POST. Rails uses a hidden +_method+ field to handle this barrier.
-
-_(highlight)The verify method in a controller can make sure that specific actions may not be used over GET_. Here is an example to verify the use of the transfer action over POST. If the action comes in using any other verb, it redirects to the list action.
-
-
-verify :method => :post, :only => [:transfer], :redirect_to => {:action => :list}
-
-
-With this precaution, the attack from above will not work, because the browser sends a GET request for images, which will not be accepted by the web application.
-
-But this was only the first step, because _(highlight)POST requests can be sent automatically, too_. Here is an example for a link which displays www.harmless.com as destination in the browser's status bar. In fact it dynamically creates a new form that sends a POST request.
-
-
-To the harmless survey
-
-
-Or the attacker places the code into the onmouseover event handler of an image:
-
-
--"name":http://www.example.com/user/signup?user=ow3ned&user[admin]=1 -- -This will set the following parameters in the controller: - - -params[:user] #=> {:name => “ow3ned”, :admin => true} - - -So if you create a new user using mass-assignment, it may be too easy to become an administrator. - -Note that this vulnerability is not restricted to database columns. Any setter method, unless explicitly protected, is accessible via the attributes= method. In fact, this vulnerability is extended even further with the introduction of nested mass assignment (and nested object forms) in rails 2.3. The +accepts_nested_attributes_for+ declaration provides us the ability to extend mass assignment to model associations (+has_many+, +has_one+, +has_and_belongs_to_many+). For example: - - - class Person < ActiveRecord::Base - has_many :credits - - accepts_nested_attributes_for :children - end - - class Child < ActiveRecord::Base - belongs_to :person - end - - -As a result, the vulnerability is extended beyond simply exposing column assignment, allowing attackers the ability to create entirely new records in referenced tables (children in this case). - -h4. Countermeasures - -To avoid this, Rails provides two class methods in your Active Record class to control access to your attributes. The +attr_protected+ method takes a list of attributes that will not be accessible for mass-assignment. For example: - - -attr_protected :admin - - -A much better way, because it follows the whitelist-principle, is the +attr_accessible+ method. It is the exact opposite of +attr_protected+, because _(highlight)it takes a list of attributes that will be accessible_. All other attributes will be protected. This way you won't forget to protect attributes when adding new ones in the course of development. Here is an example: - - -attr_accessible :name - - -If you want to set a protected attribute, you will to have to assign it individually: - - -params[:user] #=> {:name => "ow3ned", :admin => true} -@user = User.new(params[:user]) -@user.admin #=> false # not mass-assigned -@user.admin = true -@user.admin #=> true - - -A more paranoid technique to protect your whole project would be to enforce that all models whitelist their accessible attributes. This can be easily achieved with a very simple initializer: - - -ActiveRecord::Base.send(:attr_accessible, nil) - - -This will create an empty whitelist of attributes available for mass assignment for all models in your app. As such, your models will need to explicitly whitelist accessible parameters by using an +attr_accessible+ declaration. This technique is best applied at the start of a new project. However, for an existing project with a thorough set of functional tests, it should be straightforward and relatively quick to insert this initializer, run your tests, and expose each attribute (via +attr_accessible+) as dictated by your failing tests. - -h3. User Management - --- _Almost every web application has to deal with authorization and authentication. Instead of rolling your own, it is advisable to use common plug-ins. But keep them up-to-date, too. A few additional precautions can make your application even more secure._ - -There are some authorization and authentication plug-ins for Rails available. A good one saves only encrypted passwords, not plain-text passwords. The most popular plug-in is +restful_authentication+ which protects from session fixation, too. However, earlier versions allowed you to login without user name and password in certain circumstances. - -Every new user gets an activation code to activate his account when he gets an e-mail with a link in it. After activating the account, the activation_code columns will be set to NULL in the database. If someone requested an URL like these, he would be logged in as the first activated user found in the database (and chances are that this is the administrator): - -