diff options
331 files changed, 2456 insertions, 6054 deletions
diff --git a/.travis.run-test.sh b/.travis.run-test.sh new file mode 100644 index 000000000..29ba32120 --- /dev/null +++ b/.travis.run-test.sh @@ -0,0 +1,3 @@ +#! /bin/sh + +JRUBY_OPTS=-J-Xmx1024m bundle exec rake test:${TEST_SUITE} diff --git a/.travis.yml b/.travis.yml index 2ac840bc1..3abeb225f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,8 +3,6 @@ # You can also run tests on your environment. language: ruby rvm: - - 1.8.7 - - 1.9.2 - 1.9.3 - 2.0 - 2.1 @@ -34,6 +32,7 @@ script: - "bundle install" - "RUN_ON_NOT_OFFICIAL='' RUBY_VER=1.9 BRANCH=trunk bundle exec rake config/database.yml" - "bundle install" - - "JRUBY_OPTS=-J-Xmx1024m bundle exec rake ci" + - "bundle exec rake ci:setup" + - "sh .travis.run-test.sh" notifications: email: false @@ -1,12 +1,17 @@ source 'https://rubygems.org' -gem "rails", "3.2.19" +gem "rails", "4.1.6" gem "jquery-rails", "~> 3.1.1" gem "coderay", "~> 1.1.0" -gem "fastercsv", "~> 1.5.0", :platforms => [:mri_18, :mingw_18, :jruby] gem "builder", ">= 3.0.4" gem "request_store", "1.0.5" gem "mime-types" +gem "awesome_nested_set", "3.0.0" +gem "protected_attributes" +gem "actionpack-action_caching" + +# Windows does not include zoneinfo files, so bundle the tzinfo-data gem +gem 'tzinfo-data', platforms: [:mingw, :mswin, :jruby] gem "rbpdf", "~> 1.18.1" # Optional gem for LDAP authentication @@ -23,16 +28,12 @@ end platforms :mri, :mingw do # Optional gem for exporting the gantt to a PNG file, not supported with jruby group :rmagick do - # RMagick 2 supports ruby 1.9 - # RMagick 1 would be fine for ruby 1.8 but Bundler does not support - # different requirements for the same gem on different platforms gem "rmagick", ">= 2.0.0" end # Optional Markdown support, not for JRuby group :markdown do - # TODO: upgrade to redcarpet 3.x when ruby1.8 support is dropped - gem "redcarpet", "~> 2.3.0" + gem "redcarpet", "~> 3.1.2" end end @@ -57,7 +58,6 @@ if File.exist?(database_file) gem "mysql2", "~> 0.3.11", :platforms => [:mri, :mingw] gem "activerecord-jdbcmysql-adapter", :platforms => :jruby when 'mysql' - gem "mysql", "~> 2.8.1", :platforms => [:mri, :mingw] gem "activerecord-jdbcmysql-adapter", :platforms => :jruby when /postgresql/ gem "pg", ">= 0.11.0", :platforms => [:mri, :mingw] @@ -85,24 +85,20 @@ group :development do end group :test do - gem "shoulda", "~> 3.3.2" - gem "shoulda-matchers", "1.4.1" + gem "minitest" + gem "shoulda-context" gem "mocha", "~> 1.0.0", :require => 'mocha/api' - if RUBY_VERSION >= '1.9.3' - gem "capybara", "~> 2.1.0" - gem "selenium-webdriver" - end + # For running UI tests + gem "capybara", "~> 2.1.0" + gem "selenium-webdriver" end local_gemfile = File.join(File.dirname(__FILE__), "Gemfile.local") if File.exists?(local_gemfile) - puts "Loading Gemfile.local ..." if $DEBUG # `ruby -d` or `bundle -v` - instance_eval File.read(local_gemfile) + eval_gemfile local_gemfile end # Load plugins' Gemfiles Dir.glob File.expand_path("../plugins/*/{Gemfile,PluginGemfile}", __FILE__) do |file| - puts "Loading #{file} ..." if $DEBUG # `ruby -d` or `bundle -v` - #TODO: switch to "eval_gemfile file" when bundler >= 1.2.0 will be required (rails 4) - instance_eval File.read(file), file + eval_gemfile file end diff --git a/app/controllers/admin_controller.rb b/app/controllers/admin_controller.rb index c2d464d42..b0e5ce6fa 100644 --- a/app/controllers/admin_controller.rb +++ b/app/controllers/admin_controller.rb @@ -34,7 +34,7 @@ class AdminController < ApplicationController scope = Project.status(@status).order('lft') scope = scope.like(params[:name]) if params[:name].present? - @projects = scope.all + @projects = scope.to_a render :action => "projects", :layout => false if request.xhr? end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index e8f3565ee..7fedd44ff 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -496,7 +496,7 @@ class ApplicationController < ActionController::Base end def render_feed(items, options={}) - @items = items || [] + @items = (items || []).to_a @items.sort! {|x,y| y.event_datetime <=> x.event_datetime } @items = @items.slice(0, Setting.feeds_limit.to_i) @title = options[:title] || Setting.app_title diff --git a/app/controllers/auto_completes_controller.rb b/app/controllers/auto_completes_controller.rb index a48afdf90..991f0be16 100644 --- a/app/controllers/auto_completes_controller.rb +++ b/app/controllers/auto_completes_controller.rb @@ -26,7 +26,7 @@ class AutoCompletesController < ApplicationController if q.match(/\A#?(\d+)\z/) @issues << scope.find_by_id($1.to_i) end - @issues += scope.where("LOWER(#{Issue.table_name}.subject) LIKE LOWER(?)", "%#{q}%").order("#{Issue.table_name}.id DESC").limit(10).all + @issues += scope.where("LOWER(#{Issue.table_name}.subject) LIKE LOWER(?)", "%#{q}%").order("#{Issue.table_name}.id DESC").limit(10).to_a @issues.compact! end render :layout => false diff --git a/app/controllers/boards_controller.rb b/app/controllers/boards_controller.rb index 1f1d47342..04bdb56c0 100644 --- a/app/controllers/boards_controller.rb +++ b/app/controllers/boards_controller.rb @@ -25,7 +25,7 @@ class BoardsController < ApplicationController helper :watchers def index - @boards = @project.boards.includes(:project, :last_message => :author).all + @boards = @project.boards.preload(:project, :last_message => :author).to_a # show the board if there is only one if @boards.size == 1 @board = @boards.first @@ -45,12 +45,13 @@ class BoardsController < ApplicationController @topic_pages = Paginator.new @topic_count, per_page_option, params['page'] @topics = @board.topics. reorder("#{Message.table_name}.sticky DESC"). - includes(:last_reply). + joins("LEFT OUTER JOIN #{Message.table_name} last_replies_messages ON last_replies_messages.id = #{Message.table_name}.last_reply_id"). + references(:last_reply). limit(@topic_pages.per_page). offset(@topic_pages.offset). order(sort_clause). preload(:author, {:last_reply => :author}). - all + to_a @message = Message.new(:board => @board) render :action => 'show', :layout => !request.xhr? } @@ -59,7 +60,7 @@ class BoardsController < ApplicationController reorder('created_on DESC'). includes(:author, :board). limit(Setting.feeds_limit.to_i). - all + to_a render_feed(@messages, :title => "#{@project}: #{@board}") } end diff --git a/app/controllers/documents_controller.rb b/app/controllers/documents_controller.rb index 43cfc2530..47065f934 100644 --- a/app/controllers/documents_controller.rb +++ b/app/controllers/documents_controller.rb @@ -27,7 +27,7 @@ class DocumentsController < ApplicationController def index @sort_by = %w(category date title author).include?(params[:sort_by]) ? params[:sort_by] : 'category' - documents = @project.documents.includes(:attachments, :category).all + documents = @project.documents.includes(:attachments, :category).to_a case @sort_by when 'date' @grouped = documents.group_by {|d| d.updated_on.to_date } @@ -43,7 +43,7 @@ class DocumentsController < ApplicationController end def show - @attachments = @document.attachments.all + @attachments = @document.attachments.to_a end def new @@ -69,7 +69,7 @@ class DocumentsController < ApplicationController def update @document.safe_attributes = params[:document] - if request.put? and @document.save + if @document.save flash[:notice] = l(:notice_successful_update) redirect_to document_path(@document) else diff --git a/app/controllers/enumerations_controller.rb b/app/controllers/enumerations_controller.rb index 65a503974..d8d9141bb 100644 --- a/app/controllers/enumerations_controller.rb +++ b/app/controllers/enumerations_controller.rb @@ -32,7 +32,7 @@ class EnumerationsController < ApplicationController format.api { @klass = Enumeration.get_subclass(params[:type]) if @klass - @enumerations = @klass.shared.sorted.all + @enumerations = @klass.shared.sorted.to_a else render_404 end @@ -56,7 +56,7 @@ class EnumerationsController < ApplicationController end def update - if request.put? && @enumeration.update_attributes(params[:enumeration]) + if @enumeration.update_attributes(params[:enumeration]) flash[:notice] = l(:notice_successful_update) redirect_to enumerations_path else @@ -75,7 +75,7 @@ class EnumerationsController < ApplicationController redirect_to enumerations_path return end - @enumerations = @enumeration.class.system.all - [@enumeration] + @enumerations = @enumeration.class.system.to_a - [@enumeration] end private diff --git a/app/controllers/files_controller.rb b/app/controllers/files_controller.rb index 6ba5c110c..f3eb6719f 100644 --- a/app/controllers/files_controller.rb +++ b/app/controllers/files_controller.rb @@ -31,8 +31,10 @@ class FilesController < ApplicationController 'size' => "#{Attachment.table_name}.filesize", 'downloads' => "#{Attachment.table_name}.downloads" - @containers = [ Project.includes(:attachments).reorder(sort_clause).find(@project.id)] - @containers += @project.versions.includes(:attachments).reorder(sort_clause).all.sort.reverse + @containers = [Project.includes(:attachments). + references(:attachments).reorder(sort_clause).find(@project.id)] + @containers += @project.versions.includes(:attachments). + references(:attachments).reorder(sort_clause).to_a.sort.reverse render :layout => !request.xhr? end diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb index 555fc61df..45ed4c4e1 100644 --- a/app/controllers/groups_controller.rb +++ b/app/controllers/groups_controller.rb @@ -27,13 +27,13 @@ class GroupsController < ApplicationController def index respond_to do |format| format.html { - @groups = Group.sorted.all + @groups = Group.sorted.to_a @user_count_by_group_id = user_count_by_group_id } format.api { scope = Group.sorted scope = scope.givable unless params[:builtin] == '1' - @groups = scope.all + @groups = scope.to_a } end end @@ -95,7 +95,7 @@ class GroupsController < ApplicationController end def add_users - @users = User.where(:id => (params[:user_id] || params[:user_ids])).all + @users = User.where(:id => (params[:user_id] || params[:user_ids])).to_a @group.users << @users if request.post? respond_to do |format| format.html { redirect_to edit_group_path(@group, :tab => 'users') } diff --git a/app/controllers/issue_categories_controller.rb b/app/controllers/issue_categories_controller.rb index 6a956904a..3c73510ee 100644 --- a/app/controllers/issue_categories_controller.rb +++ b/app/controllers/issue_categories_controller.rb @@ -27,7 +27,7 @@ class IssueCategoriesController < ApplicationController def index respond_to do |format| format.html { redirect_to_settings_in_projects } - format.api { @categories = @project.issue_categories.all } + format.api { @categories = @project.issue_categories.to_a } end end diff --git a/app/controllers/issue_statuses_controller.rb b/app/controllers/issue_statuses_controller.rb index d305dedd7..a6b72f329 100644 --- a/app/controllers/issue_statuses_controller.rb +++ b/app/controllers/issue_statuses_controller.rb @@ -29,7 +29,7 @@ class IssueStatusesController < ApplicationController render :action => "index", :layout => false if request.xhr? } format.api { - @issue_statuses = IssueStatus.order('position').all + @issue_statuses = IssueStatus.order('position').to_a } end end diff --git a/app/controllers/issues_controller.rb b/app/controllers/issues_controller.rb index de346c576..5623c3bfa 100644 --- a/app/controllers/issues_controller.rb +++ b/app/controllers/issues_controller.rb @@ -104,15 +104,16 @@ class IssuesController < ApplicationController end def show - @journals = @issue.journals.includes(:user, :details).reorder("#{Journal.table_name}.id ASC").all + @journals = @issue.journals.includes(:user, :details). + references(:user, :details). + reorder("#{Journal.table_name}.id ASC").to_a @journals.each_with_index {|j,i| j.indice = i+1} @journals.reject!(&:private_notes?) unless User.current.allowed_to?(:view_private_notes, @issue.project) Journal.preload_journals_details_custom_fields(@journals) - # TODO: use #select! when ruby1.8 support is dropped - @journals.reject! {|journal| !journal.notes? && journal.visible_details.empty?} + @journals.select! {|journal| journal.notes? || journal.visible_details.any?} @journals.reverse! if User.current.wants_comments_in_reverse_order? - @changesets = @issue.changesets.visible.all + @changesets = @issue.changesets.visible.to_a @changesets.reverse! if User.current.wants_comments_in_reverse_order? @relations = @issue.relations.select {|r| r.other_issue(@issue) && r.other_issue(@issue).visible? } @@ -189,7 +190,7 @@ class IssuesController < ApplicationController rescue ActiveRecord::StaleObjectError @conflict = true if params[:last_journal_id] - @conflict_journals = @issue.journals_after(params[:last_journal_id]).all + @conflict_journals = @issue.journals_after(params[:last_journal_id]).to_a @conflict_journals.reject!(&:private_notes?) unless User.current.allowed_to?(:view_private_notes, @issue.project) end end @@ -301,7 +302,7 @@ class IssuesController < ApplicationController else @saved_issues = @issues @unsaved_issues = unsaved_issues - @issues = Issue.visible.where(:id => @unsaved_issues.map(&:id)).all + @issues = Issue.visible.where(:id => @unsaved_issues.map(&:id)).to_a bulk_edit render :action => 'bulk_edit' end @@ -375,7 +376,9 @@ class IssuesController < ApplicationController def update_issue_from_params @edit_allowed = User.current.allowed_to?(:edit_issues, @project) @time_entry = TimeEntry.new(:issue => @issue, :project => @issue.project) - @time_entry.attributes = params[:time_entry] + if params[:time_entry] + @time_entry.attributes = params[:time_entry] + end @issue.init_journal(User.current) @@ -422,7 +425,9 @@ class IssuesController < ApplicationController @issue.project = @project @issue.author ||= User.current # Tracker must be set before custom field values - @issue.tracker ||= @project.trackers.find((params[:issue] && params[:issue][:tracker_id]) || params[:tracker_id] || :first) + tracker_id = (params[:issue] && params[:issue][:tracker_id]) || params[:tracker_id] + tracker = tracker_id.present? ? @project.trackers.find(tracker_id) : @project.trackers.first + @issue.tracker ||= tracker if @issue.tracker.nil? render_error l(:error_no_tracker_in_project) return false diff --git a/app/controllers/journals_controller.rb b/app/controllers/journals_controller.rb index fe1c01907..940a7b5e1 100644 --- a/app/controllers/journals_controller.rb +++ b/app/controllers/journals_controller.rb @@ -34,7 +34,6 @@ class JournalsController < ApplicationController retrieve_query sort_init 'id', 'desc' sort_update(@query.sortable_columns) - if @query.valid? @journals = @query.journals(:order => "#{Journal.table_name}.created_on DESC", :limit => 25) diff --git a/app/controllers/members_controller.rb b/app/controllers/members_controller.rb index aca136754..ca5002af8 100644 --- a/app/controllers/members_controller.rb +++ b/app/controllers/members_controller.rb @@ -32,7 +32,7 @@ class MembersController < ApplicationController order("#{Member.table_name}.id"). limit(@limit). offset(@offset). - all + to_a respond_to do |format| format.html { head 406 } format.api @@ -63,7 +63,10 @@ class MembersController < ApplicationController respond_to do |format| format.html { redirect_to_settings_in_projects } - format.js { @members = members } + format.js { + @members = members + @member = Member.new + } format.api { @member = members.first if @member.valid? diff --git a/app/controllers/messages_controller.rb b/app/controllers/messages_controller.rb index 0eb9f0bef..aa0788a05 100644 --- a/app/controllers/messages_controller.rb +++ b/app/controllers/messages_controller.rb @@ -43,10 +43,10 @@ class MessagesController < ApplicationController @reply_pages = Paginator.new @reply_count, REPLIES_PER_PAGE, page @replies = @topic.children. includes(:author, :attachments, {:board => :project}). - reorder("#{Message.table_name}.created_on ASC"). + reorder("#{Message.table_name}.created_on ASC, #{Message.table_name}.id ASC"). limit(@reply_pages.per_page). offset(@reply_pages.offset). - all + to_a @reply = Message.new(:subject => "RE: #{@message.subject}") render :action => "show", :layout => false if request.xhr? diff --git a/app/controllers/my_controller.rb b/app/controllers/my_controller.rb index 714b23857..4fd18bab0 100644 --- a/app/controllers/my_controller.rb +++ b/app/controllers/my_controller.rb @@ -53,8 +53,8 @@ class MyController < ApplicationController @user = User.current @pref = @user.pref if request.post? - @user.safe_attributes = params[:user] - @user.pref.attributes = params[:pref] + @user.safe_attributes = params[:user] if params[:user] + @user.pref.attributes = params[:pref] if params[:pref] if @user.save @user.pref.save set_language_if_valid @user.language diff --git a/app/controllers/news_controller.rb b/app/controllers/news_controller.rb index ffe662921..50c0489f4 100644 --- a/app/controllers/news_controller.rb +++ b/app/controllers/news_controller.rb @@ -46,7 +46,7 @@ class NewsController < ApplicationController order("#{News.table_name}.created_on DESC"). limit(@limit). offset(@offset). - all + to_a respond_to do |format| format.html { @news = News.new # for adding news inline diff --git a/app/controllers/project_enumerations_controller.rb b/app/controllers/project_enumerations_controller.rb index 2475dbf65..df4fcbf23 100644 --- a/app/controllers/project_enumerations_controller.rb +++ b/app/controllers/project_enumerations_controller.rb @@ -20,7 +20,7 @@ class ProjectEnumerationsController < ApplicationController before_filter :authorize def update - if request.put? && params[:enumerations] + if params[:enumerations] Project.transaction do params[:enumerations].each do |id, activity| @project.update_or_create_time_entry_activity(id, activity) diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 1225f2f01..0a6b487a8 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -53,30 +53,30 @@ class ProjectsController < ApplicationController unless params[:closed] scope = scope.active end - @projects = scope.visible.order('lft').all + @projects = scope.visible.order('lft').to_a } format.api { @offset, @limit = api_offset_and_limit @project_count = Project.visible.count - @projects = Project.visible.offset(@offset).limit(@limit).order('lft').all + @projects = Project.visible.offset(@offset).limit(@limit).order('lft').to_a } format.atom { - projects = Project.visible.order('created_on DESC').limit(Setting.feeds_limit.to_i).all + projects = Project.visible.order('created_on DESC').limit(Setting.feeds_limit.to_i).to_a render_feed(projects, :title => "#{Setting.app_title}: #{l(:label_project_latest)}") } end end def new - @issue_custom_fields = IssueCustomField.sorted.all - @trackers = Tracker.sorted.all + @issue_custom_fields = IssueCustomField.sorted.to_a + @trackers = Tracker.sorted.to_a @project = Project.new @project.safe_attributes = params[:project] end def create - @issue_custom_fields = IssueCustomField.sorted.all - @trackers = Tracker.sorted.all + @issue_custom_fields = IssueCustomField.sorted.to_a + @trackers = Tracker.sorted.to_a @project = Project.new @project.safe_attributes = params[:project] @@ -109,8 +109,8 @@ class ProjectsController < ApplicationController end def copy - @issue_custom_fields = IssueCustomField.sorted.all - @trackers = Tracker.sorted.all + @issue_custom_fields = IssueCustomField.sorted.to_a + @trackers = Tracker.sorted.to_a @source_project = Project.find(params[:id]) if request.get? @project = Project.copy_from(@source_project) @@ -145,8 +145,8 @@ class ProjectsController < ApplicationController end @users_by_role = @project.users_by_role - @subprojects = @project.children.visible.all - @news = @project.news.limit(5).includes(:author, :project).reorder("#{News.table_name}.created_on DESC").all + @subprojects = @project.children.visible.to_a + @news = @project.news.limit(5).includes(:author, :project).reorder("#{News.table_name}.created_on DESC").to_a @trackers = @project.rolled_up_trackers cond = @project.project_condition(Setting.display_subprojects_issues?) @@ -167,10 +167,10 @@ class ProjectsController < ApplicationController end def settings - @issue_custom_fields = IssueCustomField.sorted.all + @issue_custom_fields = IssueCustomField.sorted.to_a @issue_category ||= IssueCategory.new @member ||= @project.members.new - @trackers = Tracker.sorted.all + @trackers = Tracker.sorted.to_a @wiki ||= @project.wiki end diff --git a/app/controllers/queries_controller.rb b/app/controllers/queries_controller.rb index 049e3534b..22ec9e929 100644 --- a/app/controllers/queries_controller.rb +++ b/app/controllers/queries_controller.rb @@ -37,8 +37,9 @@ class QueriesController < ApplicationController order("#{Query.table_name}.name"). limit(@limit). offset(@offset). - all + to_a respond_to do |format| + format.html {render_error :status => 406} format.api end end diff --git a/app/controllers/reports_controller.rb b/app/controllers/reports_controller.rb index 00c94a106..43dac3673 100644 --- a/app/controllers/reports_controller.rb +++ b/app/controllers/reports_controller.rb @@ -90,6 +90,6 @@ class ReportsController < ApplicationController private def find_issue_statuses - @statuses = IssueStatus.sorted.all + @statuses = IssueStatus.sorted.to_a end end diff --git a/app/controllers/repositories_controller.rb b/app/controllers/repositories_controller.rb index 59afc5529..7eb72865b 100644 --- a/app/controllers/repositories_controller.rb +++ b/app/controllers/repositories_controller.rb @@ -69,7 +69,7 @@ class RepositoriesController < ApplicationController @repository.merge_extra_info(attrs[:attrs_extra]) end @repository.project = @project - if request.put? && @repository.save + if @repository.save redirect_to settings_project_path(@project, :tab => 'repositories') else render :action => 'edit' @@ -94,7 +94,7 @@ class RepositoriesController < ApplicationController @committers = @repository.committers @users = @project.users additional_user_ids = @committers.collect(&:last).collect(&:to_i) - @users.collect(&:id) - @users += User.where(:id => additional_user_ids).all unless additional_user_ids.empty? + @users += User.where(:id => additional_user_ids).to_a unless additional_user_ids.empty? @users.compact! @users.sort! if request.post? && params[:committers].is_a?(Hash) @@ -145,7 +145,7 @@ class RepositoriesController < ApplicationController limit(@changeset_pages.per_page). offset(@changeset_pages.offset). includes(:user, :repository, :parents). - all + to_a respond_to do |format| format.html { render :layout => false if request.xhr? } diff --git a/app/controllers/roles_controller.rb b/app/controllers/roles_controller.rb index 8a976779e..a74d8bb91 100644 --- a/app/controllers/roles_controller.rb +++ b/app/controllers/roles_controller.rb @@ -30,7 +30,7 @@ class RolesController < ApplicationController render :action => "index", :layout => false if request.xhr? } format.api { - @roles = Role.givable.all + @roles = Role.givable.to_a } end end @@ -47,7 +47,7 @@ class RolesController < ApplicationController if params[:copy].present? && @copy_from = Role.find_by_id(params[:copy]) @role.copy_from(@copy_from) end - @roles = Role.sorted.all + @roles = Role.sorted.to_a end def create @@ -60,7 +60,7 @@ class RolesController < ApplicationController flash[:notice] = l(:notice_successful_create) redirect_to roles_path else - @roles = Role.sorted.all + @roles = Role.sorted.to_a render :action => 'new' end end @@ -69,7 +69,7 @@ class RolesController < ApplicationController end def update - if request.put? and @role.update_attributes(params[:role]) + if @role.update_attributes(params[:role]) flash[:notice] = l(:notice_successful_update) redirect_to roles_path else @@ -86,7 +86,7 @@ class RolesController < ApplicationController end def permissions - @roles = Role.sorted.all + @roles = Role.sorted.to_a @permissions = Redmine::AccessControl.permissions.select { |p| !p.public? } if request.post? @roles.each do |role| diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb index afc756677..ec8b4812c 100644 --- a/app/controllers/search_controller.rb +++ b/app/controllers/search_controller.rb @@ -31,7 +31,7 @@ class SearchController < ApplicationController when 'my_projects' User.current.memberships.collect(&:project) when 'subprojects' - @project ? (@project.self_and_descendants.active.all) : nil + @project ? (@project.self_and_descendants.active.to_a) : nil else @project end diff --git a/app/controllers/sys_controller.rb b/app/controllers/sys_controller.rb index d8ef783eb..0b62b420c 100644 --- a/app/controllers/sys_controller.rb +++ b/app/controllers/sys_controller.rb @@ -19,7 +19,8 @@ class SysController < ActionController::Base before_filter :check_enabled def projects - p = Project.active.has_module(:repository).order("#{Project.table_name}.identifier").preload(:repository).all + p = Project.active.has_module(:repository). + order("#{Project.table_name}.identifier").preload(:repository).to_a # extra_info attribute from repository breaks activeresource client render :xml => p.to_xml( :only => [:id, :identifier, :name, :is_public, :status], @@ -56,7 +57,7 @@ class SysController < ActionController::Base raise ActiveRecord::RecordNotFound unless project projects << project else - projects = scope.all + projects = scope.to_a end projects.each do |project| project.repositories.each do |repository| diff --git a/app/controllers/timelog_controller.rb b/app/controllers/timelog_controller.rb index 13923b1e5..20eccef71 100644 --- a/app/controllers/timelog_controller.rb +++ b/app/controllers/timelog_controller.rb @@ -52,7 +52,7 @@ class TimelogController < ApplicationController format.html { @entry_count = scope.count @entry_pages = Paginator.new @entry_count, per_page_option, params['page'] - @entries = scope.offset(@entry_pages.offset).limit(@entry_pages.per_page).all + @entries = scope.offset(@entry_pages.offset).limit(@entry_pages.per_page).to_a @total_hours = scope.sum(:hours).to_f render :layout => !request.xhr? @@ -60,15 +60,15 @@ class TimelogController < ApplicationController format.api { @entry_count = scope.count @offset, @limit = api_offset_and_limit - @entries = scope.offset(@offset).limit(@limit).preload(:custom_values => :custom_field).all + @entries = scope.offset(@offset).limit(@limit).preload(:custom_values => :custom_field).to_a } format.atom { - entries = scope.limit(Setting.feeds_limit.to_i).reorder("#{TimeEntry.table_name}.created_on DESC").all + entries = scope.limit(Setting.feeds_limit.to_i).reorder("#{TimeEntry.table_name}.created_on DESC").to_a render_feed(entries, :title => l(:label_spent_time)) } format.csv { # Export all entries - @entries = scope.all + @entries = scope.to_a send_data(query_to_csv(@entries, @query, params), :type => 'text/csv; header=present', :filename => 'timelog.csv') } end @@ -232,7 +232,7 @@ private end def find_time_entries - @time_entries = TimeEntry.where(:id => params[:id] || params[:ids]).all + @time_entries = TimeEntry.where(:id => params[:id] || params[:ids]).to_a raise ActiveRecord::RecordNotFound if @time_entries.empty? @projects = @time_entries.collect(&:project).compact.uniq @project = @projects.first if @projects.size == 1 diff --git a/app/controllers/trackers_controller.rb b/app/controllers/trackers_controller.rb index 02274d0d3..ec0b9ce3f 100644 --- a/app/controllers/trackers_controller.rb +++ b/app/controllers/trackers_controller.rb @@ -29,14 +29,14 @@ class TrackersController < ApplicationController render :action => "index", :layout => false if request.xhr? } format.api { - @trackers = Tracker.sorted.all + @trackers = Tracker.sorted.to_a } end end def new @tracker ||= Tracker.new(params[:tracker]) - @trackers = Tracker.sorted.all + @trackers = Tracker.sorted.to_a @projects = Project.all end @@ -95,7 +95,7 @@ class TrackersController < ApplicationController redirect_to fields_trackers_path return end - @trackers = Tracker.sorted.all + @trackers = Tracker.sorted.to_a @custom_fields = IssueCustomField.all.sort end end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index c5db58988..bb56fb285 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -47,7 +47,7 @@ class UsersController < ApplicationController @user_count = scope.count @user_pages = Paginator.new @user_count, @limit, params['page'] @offset ||= @user_pages.offset - @users = scope.order(sort_clause).limit(@limit).offset(@offset).all + @users = scope.order(sort_clause).limit(@limit).offset(@offset).to_a respond_to do |format| format.html { @@ -60,7 +60,7 @@ class UsersController < ApplicationController def show # show projects based on current user visibility - @memberships = @user.memberships.where(Project.visible_condition(User.current)).all + @memberships = @user.memberships.where(Project.visible_condition(User.current)).to_a events = Redmine::Activity::Fetcher.new(User.current, :author => @user).events(nil, nil, :limit => 10) @events_by_day = events.group_by(&:event_date) @@ -90,7 +90,7 @@ class UsersController < ApplicationController @user.admin = params[:user][:admin] || false @user.login = params[:user][:login] @user.password, @user.password_confirmation = params[:user][:password], params[:user][:password_confirmation] unless @user.auth_source_id - @user.pref.attributes = params[:pref] + @user.pref.attributes = params[:pref] if params[:pref] if @user.save Mailer.account_information(@user, @user.password).deliver if params[:send_information] @@ -134,7 +134,7 @@ class UsersController < ApplicationController # Was the account actived ? (do it before User#save clears the change) was_activated = (@user.status_change == [User::STATUS_REGISTERED, User::STATUS_ACTIVE]) # TODO: Similar to My#account - @user.pref.attributes = params[:pref] + @user.pref.attributes = params[:pref] if params[:pref] if @user.save @user.pref.save diff --git a/app/controllers/versions_controller.rb b/app/controllers/versions_controller.rb index a49f8a09a..bf2315321 100644 --- a/app/controllers/versions_controller.rb +++ b/app/controllers/versions_controller.rb @@ -31,7 +31,7 @@ class VersionsController < ApplicationController def index respond_to do |format| format.html { - @trackers = @project.trackers.sorted.all + @trackers = @project.trackers.sorted.to_a retrieve_selected_tracker_ids(@trackers, @trackers.select {|t| t.is_in_roadmap?}) @with_subprojects = params[:with_subprojects].nil? ? Setting.display_subprojects_issues? : (params[:with_subprojects] == '1') project_ids = @with_subprojects ? @project.self_and_descendants.collect(&:id) : [@project.id] @@ -56,7 +56,7 @@ class VersionsController < ApplicationController @versions.reject! {|version| !project_ids.include?(version.project_id) && @issues_by_version[version].blank?} } format.api { - @versions = @project.shared_versions.all + @versions = @project.shared_versions.to_a } end end @@ -67,7 +67,7 @@ class VersionsController < ApplicationController @issues = @version.fixed_issues.visible. includes(:status, :tracker, :priority). reorder("#{Tracker.table_name}.position, #{Issue.table_name}.id"). - all + to_a } format.api end @@ -117,7 +117,7 @@ class VersionsController < ApplicationController end def update - if request.put? && params[:version] + if params[:version] attributes = params[:version].dup attributes.delete('sharing') unless @version.allowed_sharings.include?(attributes['sharing']) @version.safe_attributes = attributes diff --git a/app/controllers/watchers_controller.rb b/app/controllers/watchers_controller.rb index e6c4d3119..ade977b41 100644 --- a/app/controllers/watchers_controller.rb +++ b/app/controllers/watchers_controller.rb @@ -53,7 +53,7 @@ class WatchersController < ApplicationController def append if params[:watcher].is_a?(Hash) user_ids = params[:watcher][:user_ids] || [params[:watcher][:user_id]] - @users = User.active.where(:id => user_ids).all + @users = User.active.where(:id => user_ids).to_a end if @users.blank? render :nothing => true @@ -92,7 +92,7 @@ class WatchersController < ApplicationController def find_watchables klass = Object.const_get(params[:object_type].camelcase) rescue nil if klass && klass.respond_to?('watched_by') - @watchables = klass.where(:id => Array.wrap(params[:object_id])).all + @watchables = klass.where(:id => Array.wrap(params[:object_id])).to_a raise Unauthorized if @watchables.any? {|w| if w.respond_to?(:visible?) !w.visible? diff --git a/app/controllers/wiki_controller.rb b/app/controllers/wiki_controller.rb index 723c7191d..9b3981655 100644 --- a/app/controllers/wiki_controller.rb +++ b/app/controllers/wiki_controller.rb @@ -219,7 +219,7 @@ class WikiController < ApplicationController reorder('version DESC'). limit(@version_pages.per_page + 1). offset(@version_pages.offset). - all + to_a render :layout => false if request.xhr? end @@ -280,7 +280,7 @@ class WikiController < ApplicationController @pages = @wiki.pages. order('title'). includes([:content, {:attachments => :author}]). - all + to_a respond_to do |format| format.html { export = render_to_string :action => 'export_multiple', :layout => false @@ -327,7 +327,7 @@ private def find_existing_or_new_page @page = @wiki.find_or_new_page(params[:id]) if @wiki.page_found_with_redirect? - redirect_to params.update(:id => @page.title) + redirect_to_page @page end end @@ -339,10 +339,14 @@ private return end if @wiki.page_found_with_redirect? - redirect_to params.update(:id => @page.title) + redirect_to_page @page end end + def redirect_to_page(page) + redirect_to :action => action_name, :project_id => page.wiki.project, :id => page.title + end + # Returns true if the current user is allowed to edit the page, otherwise false def editable?(page = @page) page.editable_by?(User.current) @@ -360,6 +364,6 @@ private reorder("#{WikiPage.table_name}.title"). includes(:wiki => :project). includes(:parent). - all + to_a end end diff --git a/app/controllers/workflows_controller.rb b/app/controllers/workflows_controller.rb index fd700d25e..28b0f2242 100644 --- a/app/controllers/workflows_controller.rb +++ b/app/controllers/workflows_controller.rb @@ -86,9 +86,9 @@ class WorkflowsController < ApplicationController @source_role = Role.find_by_id(params[:source_role_id].to_i) end @target_trackers = params[:target_tracker_ids].blank? ? - nil : Tracker.where(:id => params[:target_tracker_ids]).all + nil : Tracker.where(:id => params[:target_tracker_ids]).to_a @target_roles = params[:target_role_ids].blank? ? - nil : Role.where(:id => params[:target_role_ids]).all + nil : Role.where(:id => params[:target_role_ids]).to_a if request.post? if params[:source_tracker_id].blank? || params[:source_role_id].blank? || (@source_tracker.nil? && @source_role.nil?) flash.now[:error] = l(:error_workflow_copy_source) @@ -113,9 +113,9 @@ class WorkflowsController < ApplicationController def find_roles ids = Array.wrap(params[:role_id]) if ids == ['all'] - @roles = Role.sorted.all + @roles = Role.sorted.to_a elsif ids.present? - @roles = Role.where(:id => ids).all + @roles = Role.where(:id => ids).to_a end @roles = nil if @roles.blank? end @@ -123,9 +123,9 @@ class WorkflowsController < ApplicationController def find_trackers ids = Array.wrap(params[:tracker_id]) if ids == ['all'] - @trackers = Tracker.sorted.all + @trackers = Tracker.sorted.to_a elsif ids.present? - @trackers = Tracker.where(:id => ids).all + @trackers = Tracker.where(:id => ids).to_a end @trackers = nil if @trackers.blank? end @@ -135,6 +135,6 @@ class WorkflowsController < ApplicationController if @trackers && @used_statuses_only @statuses = @trackers.map(&:issue_statuses).flatten.uniq.sort.presence end - @statuses ||= IssueStatus.sorted.all + @statuses ||= IssueStatus.sorted.to_a end end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 6b5dd08e0..0cb4c4c00 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -138,9 +138,7 @@ module ApplicationHelper if project.archived? h(project.name) elsif options.key?(:action) - ActiveSupport::Deprecation.warn "#link_to_project with :action option is deprecated and will be removed in Redmine 3.0." - url = {:controller => 'projects', :action => 'show', :id => project}.merge(options) - link_to project.name, url, html_options + raise "#link_to_project no longer accepts :action option in Redmine 3.0" else link_to project.name, project_path(project, options), html_options end @@ -157,13 +155,6 @@ module ApplicationHelper end end - # Generates a link to a version - def link_to_version(version, options = {}) - return '' unless version && version.is_a?(Version) - options = {:title => format_date(version.effective_date)}.merge(options) - link_to_if version.visible?, format_version_name(version), version_path(version), options - end - # Helper that formats object for html or text rendering def format_object(object, html=true, &block) if block_given? @@ -185,7 +176,7 @@ module ApplicationHelper when 'Project' html ? link_to_project(object) : object.to_s when 'Version' - html ? link_to_version(object) : object.to_s + html ? link_to(object.name, version_path(object)) : object.to_s when 'TrueClass' l(:general_text_Yes) when 'FalseClass' @@ -247,7 +238,7 @@ module ApplicationHelper end def format_version_name(version) - if !version.shared? || version.project == @project + if version.project == @project h(version) else h("#{version.project} - #{version}") @@ -502,7 +493,7 @@ module ApplicationHelper h(Setting.app_title) else b = [] - ancestors = (@project.root? ? [] : @project.ancestors.visible.all) + ancestors = (@project.root? ? [] : @project.ancestors.visible.to_a) if ancestors.any? root = ancestors.shift b << link_to_project(root, {:jump => current_menu_item}, :class => 'root') @@ -1217,7 +1208,7 @@ module ApplicationHelper source end end - super sources, options + super *sources, options end # Overrides Rails' image_tag with themes and plugins support. @@ -1250,7 +1241,7 @@ module ApplicationHelper end end end - super sources, options + super *sources, options end # TODO: remove this in 2.5.0 @@ -1288,12 +1279,7 @@ module ApplicationHelper end def sanitize_anchor_name(anchor) - if ''.respond_to?(:encoding) || RUBY_PLATFORM == 'java' - anchor.gsub(%r{[^\s\-\p{Word}]}, '').gsub(%r{\s+(\-+\s*)?}, '-') - else - # TODO: remove when ruby1.8 is no longer supported - anchor.gsub(%r{[^\w\s\-]}, '').gsub(%r{\s+(\-+\s*)?}, '-') - end + anchor.gsub(%r{[^\s\-\p{Word}]}, '').gsub(%r{\s+(\-+\s*)?}, '-') end # Returns the javascript tags that are included in the html layout head diff --git a/app/helpers/groups_helper.rb b/app/helpers/groups_helper.rb index 4777328b0..315be99fc 100644 --- a/app/helpers/groups_helper.rb +++ b/app/helpers/groups_helper.rb @@ -30,7 +30,7 @@ module GroupsHelper scope = User.active.sorted.not_in_group(group).like(params[:q]) principal_count = scope.count principal_pages = Redmine::Pagination::Paginator.new principal_count, 100, params['page'] - principals = scope.offset(principal_pages.offset).limit(principal_pages.per_page).all + principals = scope.offset(principal_pages.offset).limit(principal_pages.per_page).to_a s = content_tag('div', principals_check_box_tags('user_ids[]', principals), :id => 'principals') diff --git a/app/helpers/issues_helper.rb b/app/helpers/issues_helper.rb index 8d7f9641c..9760a8ebb 100644 --- a/app/helpers/issues_helper.rb +++ b/app/helpers/issues_helper.rb @@ -63,7 +63,7 @@ module IssuesHelper def render_issue_subject_with_tree(issue) s = '' - ancestors = issue.root? ? [] : issue.ancestors.visible.all + ancestors = issue.root? ? [] : issue.ancestors.visible.to_a ancestors.each do |ancestor| s << '<div>' + content_tag('p', link_to_issue(ancestor, :project => (issue.project_id != ancestor.project_id))) end @@ -204,7 +204,7 @@ module IssuesHelper order("#{Query.table_name}.name ASC"). # Project specific queries and global queries where(@project.nil? ? ["project_id IS NULL"] : ["project_id IS NULL OR project_id = ?", @project.id]). - all + to_a end @sidebar_queries end @@ -408,7 +408,7 @@ module IssuesHelper if association record = association.class_name.constantize.find_by_id(id) if record - record.name.force_encoding('UTF-8') if record.name.respond_to?(:force_encoding) + record.name.force_encoding('UTF-8') return record.name end end diff --git a/app/helpers/members_helper.rb b/app/helpers/members_helper.rb index 5e98643db..4aae46475 100644 --- a/app/helpers/members_helper.rb +++ b/app/helpers/members_helper.rb @@ -22,7 +22,7 @@ module MembersHelper scope = Principal.active.sorted.not_member_of(project).like(params[:q]) principal_count = scope.count principal_pages = Redmine::Pagination::Paginator.new principal_count, 100, params['page'] - principals = scope.offset(principal_pages.offset).limit(principal_pages.per_page).all + principals = scope.offset(principal_pages.offset).limit(principal_pages.per_page).to_a s = content_tag('div', principals_check_box_tags('membership[user_ids][]', principals), :id => 'principals') diff --git a/app/helpers/my_helper.rb b/app/helpers/my_helper.rb index 8e78dfbe9..5917f26ec 100644 --- a/app/helpers/my_helper.rb +++ b/app/helpers/my_helper.rb @@ -23,11 +23,12 @@ module MyHelper where(:project_id => User.current.projects.map(&:id)). where("(start_date>=? and start_date<=?) or (due_date>=? and due_date<=?)", startdt, enddt, startdt, enddt). includes(:project, :tracker, :priority, :assigned_to). - all + references(:project, :tracker, :priority, :assigned_to). + to_a end def documents_items - Document.visible.order("#{Document.table_name}.created_on DESC").limit(10).all + Document.visible.order("#{Document.table_name}.created_on DESC").limit(10).to_a end def issuesassignedtome_items @@ -35,8 +36,9 @@ module MyHelper where(:assigned_to_id => ([User.current.id] + User.current.group_ids)). limit(10). includes(:status, :project, :tracker, :priority). + references(:status, :project, :tracker, :priority). order("#{IssuePriority.table_name}.position DESC, #{Issue.table_name}.updated_on DESC"). - all + to_a end def issuesreportedbyme_items @@ -44,12 +46,13 @@ module MyHelper where(:author_id => User.current.id). limit(10). includes(:status, :project, :tracker). + references(:status, :project, :tracker). order("#{Issue.table_name}.updated_on DESC"). - all + to_a end def issueswatched_items - Issue.visible.on_active_project.watched_by(User.current.id).recently_updated.limit(10).all + Issue.visible.on_active_project.watched_by(User.current.id).recently_updated.limit(10).to_a end def news_items @@ -57,15 +60,17 @@ module MyHelper where(:project_id => User.current.projects.map(&:id)). limit(10). includes(:project, :author). + references(:project, :author). order("#{News.table_name}.created_on DESC"). - all + to_a end def timelog_items TimeEntry. where("#{TimeEntry.table_name}.user_id = ? AND #{TimeEntry.table_name}.spent_on BETWEEN ? AND ?", User.current.id, Date.today - 6, Date.today). - includes(:activity, :project, {:issue => [:tracker, :status]}). + joins(:activity, :project, {:issue => [:tracker, :status]}). + references(:activity, :project, {:issue => [:tracker, :status]}). order("#{TimeEntry.table_name}.spent_on DESC, #{Project.table_name}.name ASC, #{Tracker.table_name}.position ASC, #{Issue.table_name}.id ASC"). - all + to_a end end diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index 8e23ccdda..e23ebab99 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -18,6 +18,11 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. module ProjectsHelper + def link_to_version(version, options = {}) + return '' unless version && version.is_a?(Version) + link_to_if version.visible?, format_version_name(version), version_path(version), options + end + def project_settings_tabs tabs = [{:name => 'info', :action => :edit_project, :partial => 'projects/edit', :label => :label_information_plural}, {:name => 'modules', :action => :select_project_modules, :partial => 'projects/settings/modules', :label => :label_module_plural}, diff --git a/app/helpers/queries_helper.rb b/app/helpers/queries_helper.rb index ca8d2537b..0206b160a 100644 --- a/app/helpers/queries_helper.rb +++ b/app/helpers/queries_helper.rb @@ -143,7 +143,7 @@ module QueriesHelper end end - export = FCSV.generate(:col_sep => l(:general_csv_separator)) do |csv| + export = CSV.generate(:col_sep => l(:general_csv_separator)) do |csv| # csv header fields csv << columns.collect {|c| Redmine::CodesetUtil.from_utf8(c.caption.to_s, encoding) } # csv lines diff --git a/app/helpers/search_helper.rb b/app/helpers/search_helper.rb index a39686b3d..15433750a 100644 --- a/app/helpers/search_helper.rb +++ b/app/helpers/search_helper.rb @@ -29,7 +29,6 @@ module SearchHelper result << '...' break end - words = words.mb_chars if i.even? result << h(words.length > 100 ? "#{words.slice(0..44)} ... #{words.slice(-45..-1)}" : words) else diff --git a/app/helpers/sort_helper.rb b/app/helpers/sort_helper.rb index cbdc41883..da74aeac2 100644 --- a/app/helpers/sort_helper.rb +++ b/app/helpers/sort_helper.rb @@ -84,7 +84,8 @@ module SortHelper def to_sql sql = @criteria.collect do |k,o| if s = @available_criteria[k] - (o ? s.to_a : s.to_a.collect {|c| append_desc(c)}) + s = [s] unless s.is_a?(Array) + (o ? s : s.collect {|c| append_desc(c)}) end end.flatten.compact sql.blank? ? nil : sql diff --git a/app/helpers/timelog_helper.rb b/app/helpers/timelog_helper.rb index 02532c3f1..c68d2c0c5 100644 --- a/app/helpers/timelog_helper.rb +++ b/app/helpers/timelog_helper.rb @@ -105,7 +105,7 @@ module TimelogHelper def report_to_csv(report) decimal_separator = l(:general_csv_decimal_separator) - export = FCSV.generate(:col_sep => l(:general_csv_separator)) do |csv| + export = CSV.generate(:col_sep => l(:general_csv_separator)) do |csv| # Column headers headers = report.criteria.collect {|criteria| l(report.available_criteria[criteria][:label]) } headers += report.periods diff --git a/app/models/attachment.rb b/app/models/attachment.rb index f36f7cccf..9d7e03247 100644 --- a/app/models/attachment.rb +++ b/app/models/attachment.rb @@ -27,6 +27,7 @@ class Attachment < ActiveRecord::Base validates_length_of :disk_filename, :maximum => 255 validates_length_of :description, :maximum => 255 validate :validate_max_file_size + attr_protected :id acts_as_event :title => :filename, :url => Proc.new {|o| {:controller => 'attachments', :action => 'download', :id => o.id, :filename => o.filename}} @@ -34,16 +35,16 @@ class Attachment < ActiveRecord::Base acts_as_activity_provider :type => 'files', :permission => :view_files, :author_key => :author_id, - :find_options => {:select => "#{Attachment.table_name}.*", - :joins => "LEFT JOIN #{Version.table_name} ON #{Attachment.table_name}.container_type='Version' AND #{Version.table_name}.id = #{Attachment.table_name}.container_id " + - "LEFT JOIN #{Project.table_name} ON #{Version.table_name}.project_id = #{Project.table_name}.id OR ( #{Attachment.table_name}.container_type='Project' AND #{Attachment.table_name}.container_id = #{Project.table_name}.id )"} + :scope => select("#{Attachment.table_name}.*"). + joins("LEFT JOIN #{Version.table_name} ON #{Attachment.table_name}.container_type='Version' AND #{Version.table_name}.id = #{Attachment.table_name}.container_id " + + "LEFT JOIN #{Project.table_name} ON #{Version.table_name}.project_id = #{Project.table_name}.id OR ( #{Attachment.table_name}.container_type='Project' AND #{Attachment.table_name}.container_id = #{Project.table_name}.id )") acts_as_activity_provider :type => 'documents', :permission => :view_documents, :author_key => :author_id, - :find_options => {:select => "#{Attachment.table_name}.*", - :joins => "LEFT JOIN #{Document.table_name} ON #{Attachment.table_name}.container_type='Document' AND #{Document.table_name}.id = #{Attachment.table_name}.container_id " + - "LEFT JOIN #{Project.table_name} ON #{Document.table_name}.project_id = #{Project.table_name}.id"} + :scope => select("#{Attachment.table_name}.*"). + joins("LEFT JOIN #{Document.table_name} ON #{Attachment.table_name}.container_type='Document' AND #{Document.table_name}.id = #{Attachment.table_name}.container_id " + + "LEFT JOIN #{Project.table_name} ON #{Document.table_name}.project_id = #{Project.table_name}.id") cattr_accessor :storage_path @@storage_path = Redmine::Configuration['attachments_storage_path'] || File.join(Rails.root, "files") @@ -74,7 +75,7 @@ class Attachment < ActiveRecord::Base if @temp_file.size > 0 if @temp_file.respond_to?(:original_filename) self.filename = @temp_file.original_filename - self.filename.force_encoding("UTF-8") if filename.respond_to?(:force_encoding) + self.filename.force_encoding("UTF-8") end if @temp_file.respond_to?(:content_type) self.content_type = @temp_file.content_type.to_s.chomp diff --git a/app/models/auth_source.rb b/app/models/auth_source.rb index 1494e161a..aa2506e5b 100644 --- a/app/models/auth_source.rb +++ b/app/models/auth_source.rb @@ -29,6 +29,7 @@ class AuthSource < ActiveRecord::Base validates_presence_of :name validates_uniqueness_of :name validates_length_of :name, :maximum => 60 + attr_protected :id def authenticate(login, password) end diff --git a/app/models/board.rb b/app/models/board.rb index 387792cb4..2cbeb0a8a 100644 --- a/app/models/board.rb +++ b/app/models/board.rb @@ -18,8 +18,8 @@ class Board < ActiveRecord::Base include Redmine::SafeAttributes belongs_to :project - has_many :topics, :class_name => 'Message', :conditions => "#{Message.table_name}.parent_id IS NULL", :order => "#{Message.table_name}.created_on DESC" - has_many :messages, :dependent => :destroy, :order => "#{Message.table_name}.created_on DESC" + has_many :topics, lambda {where("#{Message.table_name}.parent_id IS NULL").order("#{Message.table_name}.created_on DESC")}, :class_name => 'Message' + has_many :messages, lambda {order("#{Message.table_name}.created_on DESC")}, :dependent => :destroy belongs_to :last_message, :class_name => 'Message', :foreign_key => :last_message_id acts_as_tree :dependent => :nullify acts_as_list :scope => '(project_id = #{project_id} AND parent_id #{parent_id ? "= #{parent_id}" : "IS NULL"})' @@ -29,9 +29,12 @@ class Board < ActiveRecord::Base validates_length_of :name, :maximum => 30 validates_length_of :description, :maximum => 255 validate :validate_board + attr_protected :id scope :visible, lambda {|*args| - includes(:project).where(Project.allowed_to_condition(args.shift || User.current, :view_messages, *args)) + joins(:project). + references(:project). + where(Project.allowed_to_condition(args.shift || User.current, :view_messages, *args)) } safe_attributes 'name', 'description', 'parent_id', 'move_to' diff --git a/app/models/change.rb b/app/models/change.rb index 6ef56e0de..b24c1bd54 100644 --- a/app/models/change.rb +++ b/app/models/change.rb @@ -21,6 +21,7 @@ class Change < ActiveRecord::Base validates_presence_of :changeset_id, :action, :path before_save :init_path before_validation :replace_invalid_utf8_of_path + attr_protected :id def relative_path changeset.repository.relative_path(path) diff --git a/app/models/changeset.rb b/app/models/changeset.rb index cf58c6e07..b12ea6778 100644 --- a/app/models/changeset.rb +++ b/app/models/changeset.rb @@ -35,20 +35,23 @@ class Changeset < ActiveRecord::Base :url => Proc.new {|o| {:controller => 'repositories', :action => 'revision', :id => o.repository.project, :repository_id => o.repository.identifier_param, :rev => o.identifier}} acts_as_searchable :columns => 'comments', - :include => {:repository => :project}, + :scope => preload(:repository => :project), :project_key => "#{Repository.table_name}.project_id", :date_column => 'committed_on' acts_as_activity_provider :timestamp => "#{table_name}.committed_on", :author_key => :user_id, - :find_options => {:include => [:user, {:repository => :project}]} + :scope => preload(:user, {:repository => :project}) validates_presence_of :repository_id, :revision, :committed_on, :commit_date validates_uniqueness_of :revision, :scope => :repository_id validates_uniqueness_of :scmid, :scope => :repository_id, :allow_nil => true + attr_protected :id scope :visible, lambda {|*args| - includes(:repository => :project).where(Project.allowed_to_condition(args.shift || User.current, :view_changesets, *args)) + joins(:repository => :project). + references(:repository => :project). + where(Project.allowed_to_condition(args.shift || User.current, :view_changesets, *args)) } after_create :scan_for_issues diff --git a/app/models/comment.rb b/app/models/comment.rb index 02d9a3b36..9893ad664 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -21,6 +21,7 @@ class Comment < ActiveRecord::Base belongs_to :author, :class_name => 'User', :foreign_key => 'author_id' validates_presence_of :commented, :author, :comments + attr_protected :id after_create :send_notification diff --git a/app/models/custom_field.rb b/app/models/custom_field.rb index 48ef2c7cc..f3829bf70 100644 --- a/app/models/custom_field.rb +++ b/app/models/custom_field.rb @@ -29,6 +29,7 @@ class CustomField < ActiveRecord::Base validates_length_of :name, :maximum => 30 validates_inclusion_of :field_format, :in => Proc.new { Redmine::FieldFormat.available_formats } validate :validate_custom_field + attr_protected :id before_validation :set_searchable before_save do |field| @@ -117,7 +118,7 @@ class CustomField < ActiveRecord::Base values = read_attribute(:possible_values) if values.is_a?(Array) values.each do |value| - value.force_encoding('UTF-8') if value.respond_to?(:force_encoding) + value.force_encoding('UTF-8') end values else @@ -218,7 +219,7 @@ class CustomField < ActiveRecord::Base # to move in project_custom_field def self.for_all - where(:is_for_all => true).order('position').all + where(:is_for_all => true).order('position').to_a end def type_name diff --git a/app/models/custom_value.rb b/app/models/custom_value.rb index 952646311..ab2eee744 100644 --- a/app/models/custom_value.rb +++ b/app/models/custom_value.rb @@ -18,6 +18,7 @@ class CustomValue < ActiveRecord::Base belongs_to :custom_field belongs_to :customized, :polymorphic => true + attr_protected :id def initialize(attributes=nil, *args) super diff --git a/app/models/document.rb b/app/models/document.rb index 4609d8602..c195f64ca 100644 --- a/app/models/document.rb +++ b/app/models/document.rb @@ -21,19 +21,23 @@ class Document < ActiveRecord::Base belongs_to :category, :class_name => "DocumentCategory", :foreign_key => "category_id" acts_as_attachable :delete_permission => :delete_documents - acts_as_searchable :columns => ['title', "#{table_name}.description"], :include => :project + acts_as_searchable :columns => ['title', "#{table_name}.description"], + :scope => preload(:project) acts_as_event :title => Proc.new {|o| "#{l(:label_document)}: #{o.title}"}, :author => Proc.new {|o| o.attachments.reorder("#{Attachment.table_name}.created_on ASC").first.try(:author) }, :url => Proc.new {|o| {:controller => 'documents', :action => 'show', :id => o.id}} - acts_as_activity_provider :find_options => {:include => :project} + acts_as_activity_provider :scope => preload(:project) validates_presence_of :project, :title, :category validates_length_of :title, :maximum => 60 + attr_protected :id after_create :send_notification scope :visible, lambda {|*args| - includes(:project).where(Project.allowed_to_condition(args.shift || User.current, :view_documents, *args)) + joins(:project). + references(:project). + where(Project.allowed_to_condition(args.shift || User.current, :view_documents, *args)) } safe_attributes 'category_id', 'title', 'description' diff --git a/app/models/enabled_module.rb b/app/models/enabled_module.rb index 1cc84aaa5..baf6cdd11 100644 --- a/app/models/enabled_module.rb +++ b/app/models/enabled_module.rb @@ -21,6 +21,7 @@ class EnabledModule < ActiveRecord::Base validates_presence_of :name validates_uniqueness_of :name, :scope => :project_id + attr_protected :id after_create :module_enabled diff --git a/app/models/enumeration.rb b/app/models/enumeration.rb index b4b64b7fc..8c82a0dc8 100644 --- a/app/models/enumeration.rb +++ b/app/models/enumeration.rb @@ -18,7 +18,7 @@ class Enumeration < ActiveRecord::Base include Redmine::SubclassFactory - default_scope :order => "#{Enumeration.table_name}.position ASC" + default_scope lambda {order("#{Enumeration.table_name}.position ASC")} belongs_to :project diff --git a/app/models/group.rb b/app/models/group.rb index 7b82d1c1f..b9d4d9ef4 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -28,6 +28,7 @@ class Group < Principal validates_presence_of :lastname validates_uniqueness_of :lastname, :case_sensitive => false validates_length_of :lastname, :maximum => 255 + attr_protected :id before_destroy :remove_references_before_destroy @@ -81,7 +82,8 @@ class Group < Principal def user_removed(user) members.each do |member| MemberRole. - includes(:member). + joins(:member). + references(:member). where("#{Member.table_name}.user_id = ? AND #{MemberRole.table_name}.inherited_from IN (?)", user.id, member.member_role_ids). each(&:destroy) end @@ -95,10 +97,6 @@ class Group < Principal super(attr_name, *args) end - def self.builtin_id(arg) - (arg.anonymous? ? GroupAnonymous : GroupNonMember).instance_id - end - def self.anonymous GroupAnonymous.load_instance end diff --git a/app/models/group_anonymous.rb b/app/models/group_anonymous.rb index c3c821bb2..a6d01853d 100644 --- a/app/models/group_anonymous.rb +++ b/app/models/group_anonymous.rb @@ -23,8 +23,4 @@ class GroupAnonymous < GroupBuiltin def builtin_type "anonymous" end - - def self.instance_id - @@instance_id ||= load_instance.id - end end diff --git a/app/models/group_builtin.rb b/app/models/group_builtin.rb index 71ecc06ab..538a89eea 100644 --- a/app/models/group_builtin.rb +++ b/app/models/group_builtin.rb @@ -37,7 +37,7 @@ class GroupBuiltin < Group class << self def load_instance return nil if self == GroupBuiltin - instance = first(:order => 'id') || create_instance + instance = order('id').first || create_instance end def create_instance diff --git a/app/models/group_non_member.rb b/app/models/group_non_member.rb index 8b3dfd4aa..9f78f0b46 100644 --- a/app/models/group_non_member.rb +++ b/app/models/group_non_member.rb @@ -23,8 +23,4 @@ class GroupNonMember < GroupBuiltin def builtin_type "non_member" end - - def self.instance_id - @@instance_id ||= load_instance.id - end end diff --git a/app/models/issue.rb b/app/models/issue.rb index 1c1c99dec..bb45a6f58 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -31,15 +31,12 @@ class Issue < ActiveRecord::Base has_many :journals, :as => :journalized, :dependent => :destroy has_many :visible_journals, + lambda {where(["(#{Journal.table_name}.private_notes = ? OR (#{Project.allowed_to_condition(User.current, :view_private_notes)}))", false])}, :class_name => 'Journal', - :as => :journalized, - :conditions => Proc.new { - ["(#{Journal.table_name}.private_notes = ? OR (#{Project.allowed_to_condition(User.current, :view_private_notes)}))", false] - }, - :readonly => true + :as => :journalized has_many :time_entries, :dependent => :destroy - has_and_belongs_to_many :changesets, :order => "#{Changeset.table_name}.committed_on ASC, #{Changeset.table_name}.id ASC" + has_and_belongs_to_many :changesets, lambda {order("#{Changeset.table_name}.committed_on ASC, #{Changeset.table_name}.id ASC")} has_many :relations_from, :class_name => 'IssueRelation', :foreign_key => 'issue_from_id', :dependent => :delete_all has_many :relations_to, :class_name => 'IssueRelation', :foreign_key => 'issue_to_id', :dependent => :delete_all @@ -49,14 +46,19 @@ class Issue < ActiveRecord::Base acts_as_customizable acts_as_watchable acts_as_searchable :columns => ['subject', "#{table_name}.description", "#{Journal.table_name}.notes"], - :include => [:project, :visible_journals], # sort by id so that limited eager loading doesn't break with postgresql - :order_column => "#{table_name}.id" + :order_column => "#{table_name}.id", + :scope => lambda { joins(:project). + joins("LEFT OUTER JOIN #{Journal.table_name} ON #{Journal.table_name}.journalized_type='Issue'" + + " AND #{Journal.table_name}.journalized_id = #{Issue.table_name}.id" + + " AND (#{Journal.table_name}.private_notes = #{connection.quoted_false}" + + " OR (#{Project.allowed_to_condition(User.current, :view_private_notes)}))") } + acts_as_event :title => Proc.new {|o| "#{o.tracker.name} ##{o.id} (#{o.status}): #{o.subject}"}, :url => Proc.new {|o| {:controller => 'issues', :action => 'show', :id => o.id}}, :type => Proc.new {|o| 'issue' + (o.closed? ? ' closed' : '') } - acts_as_activity_provider :find_options => {:include => [:project, :author, :tracker]}, + acts_as_activity_provider :scope => preload(:project, :author, :tracker), :author_key => :author_id DONE_RATIO_OPTIONS = %w(issue_field issue_status) @@ -72,19 +74,26 @@ class Issue < ActiveRecord::Base validates :start_date, :date => true validates :due_date, :date => true validate :validate_issue, :validate_required_fields + attr_protected :id scope :visible, lambda {|*args| - includes(:project).where(Issue.visible_condition(args.shift || User.current, *args)) + joins(:project). + references(:project). + where(Issue.visible_condition(args.shift || User.current, *args)) } scope :open, lambda {|*args| is_closed = args.size > 0 ? !args.first : false - includes(:status).where("#{IssueStatus.table_name}.is_closed = ?", is_closed) + joins(:status). + references(:status). + where("#{IssueStatus.table_name}.is_closed = ?", is_closed) } scope :recently_updated, lambda { order("#{Issue.table_name}.updated_on DESC") } scope :on_active_project, lambda { - includes(:status, :project, :tracker).where("#{Project.table_name}.status = ?", Project::STATUS_ACTIVE) + joins(:project). + references(:project). + where("#{Project.table_name}.status = ?", Project::STATUS_ACTIVE) } scope :fixed_version, lambda {|versions| ids = [versions].flatten.compact.map {|v| v.is_a?(Version) ? v.id : v} @@ -107,7 +116,7 @@ class Issue < ActiveRecord::Base # Returns a SQL conditions string used to find all issues visible by the specified user def self.visible_condition(user, options={}) Project.allowed_to_condition(user, :view_issues, options) do |role, user| - if user.logged? + if user.id && user.logged? case role.issues_visibility when 'all' nil @@ -351,6 +360,10 @@ class Issue < ActiveRecord::Base # Do not redefine alias chain on reload (see #4838) alias_method_chain(:assign_attributes, :project_and_tracker_first) unless method_defined?(:assign_attributes_without_project_and_tracker_first) + def attributes=(new_attributes) + assign_attributes new_attributes + end + def estimated_hours=(h) write_attribute :estimated_hours, (h.is_a?(String) ? h.to_hours : h) end @@ -423,7 +436,7 @@ class Issue < ActiveRecord::Base def safe_attributes=(attrs, user=User.current) return unless attrs.is_a?(Hash) - attrs = attrs.dup + attrs = attrs.deep_dup # Project and Tracker must be set before since new_statuses_allowed_to depends on it. if (p = attrs.delete('project_id')) && safe_attribute?('project_id') @@ -458,14 +471,12 @@ class Issue < ActiveRecord::Base if attrs['custom_field_values'].present? editable_custom_field_ids = editable_custom_field_values(user).map {|v| v.custom_field_id.to_s} - # TODO: use #select when ruby1.8 support is dropped - attrs['custom_field_values'] = attrs['custom_field_values'].reject {|k, v| !editable_custom_field_ids.include?(k.to_s)} + attrs['custom_field_values'].select! {|k, v| editable_custom_field_ids.include?(k.to_s)} end if attrs['custom_fields'].present? editable_custom_field_ids = editable_custom_field_values(user).map {|v| v.custom_field_id.to_s} - # TODO: use #select when ruby1.8 support is dropped - attrs['custom_fields'] = attrs['custom_fields'].reject {|c| !editable_custom_field_ids.include?(c['id'].to_s)} + attrs['custom_fields'].select! {|c| editable_custom_field_ids.include?(c['id'].to_s)} end # mass-assignment security bypass @@ -733,7 +744,7 @@ class Issue < ActiveRecord::Base def assignable_versions return @assignable_versions if @assignable_versions - versions = project.shared_versions.open.all + versions = project.shared_versions.open.to_a if fixed_version if fixed_version_id_changed? # nothing to do @@ -879,10 +890,14 @@ class Issue < ActiveRecord::Base if issues.any? issue_ids = issues.map(&:id) # Relations with issue_from in given issues and visible issue_to - relations_from = IssueRelation.includes(:issue_to => [:status, :project]).where(visible_condition(user)).where(:issue_from_id => issue_ids).all + relations_from = IssueRelation.joins(:issue_to => :project). + references(:issue_to => :project). + where(visible_condition(user)).where(:issue_from_id => issue_ids).to_a # Relations with issue_to in given issues and visible issue_from - relations_to = IssueRelation.includes(:issue_from => [:status, :project]).where(visible_condition(user)).where(:issue_to_id => issue_ids).all - + relations_to = IssueRelation.joins(:issue_from => :project). + references(:issue_from => :project). + where(visible_condition(user)). + where(:issue_to_id => issue_ids).to_a issues.each do |issue| relations = relations_from.select {|relation| relation.issue_from_id == issue.id} + @@ -1121,6 +1136,7 @@ class Issue < ActiveRecord::Base def parent_issue_id=(arg) s = arg.to_s.strip.presence if s && (m = s.match(%r{\A#?(\d+)\z})) && (@parent_issue = Issue.find_by_id(m[1])) + @parent_issue.id @invalid_parent_issue_id = nil elsif s.blank? @parent_issue = nil @@ -1349,7 +1365,7 @@ class Issue < ActiveRecord::Base self.root_id = (@parent_issue.nil? ? id : @parent_issue.root_id) cond = ["root_id = ? AND lft >= ? AND rgt <= ? ", old_root_id, lft, rgt] self.class.base_class.select('id').lock(true).where(cond) - offset = right_most_bound + 1 - lft + offset = rdm_right_most_bound + 1 - lft Issue.where(cond). update_all(["root_id = ?, lft = lft + ?, rgt = rgt + ?", root_id, offset, offset]) end @@ -1367,6 +1383,14 @@ class Issue < ActiveRecord::Base recalculate_attributes_for(former_parent_id) if former_parent_id end + def rdm_right_most_bound + right_most_node = + self.class.base_class.unscoped. + order("#{quoted_right_column_full_name} desc").limit(1).lock(true).first + right_most_node ? (right_most_node[right_column_name] || 0 ) : 0 + end + private :rdm_right_most_bound + def update_parent_attributes recalculate_attributes_for(parent_id) if parent_id end @@ -1395,7 +1419,7 @@ class Issue < ActiveRecord::Base end done = p.leaves.joins(:status). sum("COALESCE(CASE WHEN estimated_hours > 0 THEN estimated_hours ELSE NULL END, #{average}) " + - "* (CASE WHEN is_closed = #{connection.quoted_true} THEN 100 ELSE COALESCE(done_ratio, 0) END)").to_f + "* (CASE WHEN is_closed = #{self.class.connection.quoted_true} THEN 100 ELSE COALESCE(done_ratio, 0) END)").to_f progress = done / (average * leaves_count) p.done_ratio = progress.round end @@ -1415,7 +1439,8 @@ class Issue < ActiveRecord::Base def self.update_versions(conditions=nil) # Only need to update issues with a fixed_version from # a different project and that is not systemwide shared - Issue.includes(:project, :fixed_version). + Issue.joins(:project, :fixed_version). + references(:version, :fixed_version). where("#{Issue.table_name}.fixed_version_id IS NOT NULL" + " AND #{Issue.table_name}.project_id <> #{Version.table_name}.project_id" + " AND #{Version.table_name}.sharing <> 'system'"). diff --git a/app/models/issue_category.rb b/app/models/issue_category.rb index 7bee6f234..e5e508861 100644 --- a/app/models/issue_category.rb +++ b/app/models/issue_category.rb @@ -24,6 +24,7 @@ class IssueCategory < ActiveRecord::Base validates_presence_of :name validates_uniqueness_of :name, :scope => [:project_id] validates_length_of :name, :maximum => 30 + attr_protected :id safe_attributes 'name', 'assigned_to_id' diff --git a/app/models/issue_custom_field.rb b/app/models/issue_custom_field.rb index a1d16333d..42695e461 100644 --- a/app/models/issue_custom_field.rb +++ b/app/models/issue_custom_field.rb @@ -32,7 +32,7 @@ class IssueCustomField < CustomField sql = super id_column ||= id tracker_condition = "#{Issue.table_name}.tracker_id IN (SELECT tracker_id FROM #{table_name_prefix}custom_fields_trackers#{table_name_suffix} WHERE custom_field_id = #{id_column})" - project_condition = "EXISTS (SELECT 1 FROM #{CustomField.table_name} ifa WHERE ifa.is_for_all = #{connection.quoted_true} AND ifa.id = #{id_column})" + + project_condition = "EXISTS (SELECT 1 FROM #{CustomField.table_name} ifa WHERE ifa.is_for_all = #{self.class.connection.quoted_true} AND ifa.id = #{id_column})" + " OR #{Issue.table_name}.project_id IN (SELECT project_id FROM #{table_name_prefix}custom_fields_projects#{table_name_suffix} WHERE custom_field_id = #{id_column})" "((#{sql}) AND (#{tracker_condition}) AND (#{project_condition}))" diff --git a/app/models/issue_query.rb b/app/models/issue_query.rb index c9115100c..9ca0f3077 100644 --- a/app/models/issue_query.rb +++ b/app/models/issue_query.rb @@ -45,7 +45,9 @@ class IssueQuery < Query scope :visible, lambda {|*args| user = args.shift || User.current base = Project.allowed_to_condition(user, :view_issues, *args) - scope = includes(:project).where("#{table_name}.project_id IS NULL OR (#{base})") + scope = joins("LEFT OUTER JOIN #{Project.table_name} ON #{table_name}.project_id = #{Project.table_name}.id"). + references(:project). + where("#{table_name}.project_id IS NULL OR (#{base})") if user.admin? scope.where("#{table_name}.visibility <> ? OR #{table_name}.user_id = ?", VISIBILITY_PRIVATE, user.id) @@ -132,17 +134,17 @@ class IssueQuery < Query if project principals += project.principals.sort unless project.leaf? - subprojects = project.descendants.visible.all + subprojects = project.descendants.visible.to_a principals += Principal.member_of(subprojects) end - versions = project.shared_versions.all - categories = project.issue_categories.all + versions = project.shared_versions.to_a + categories = project.issue_categories.to_a issue_custom_fields = project.all_issue_custom_fields else if all_projects.any? principals += Principal.member_of(all_projects) end - versions = Version.visible.where(:sharing => 'system').all + versions = Version.visible.where(:sharing => 'system').to_a issue_custom_fields = IssueCustomField.where(:is_for_all => true) end principals.uniq! @@ -339,7 +341,7 @@ class IssueQuery < Query scope = scope.preload(:author) end - issues = scope.all + issues = scope.to_a if has_column?(:spent_hours) Issue.load_visible_spent_hours(issues) @@ -360,12 +362,13 @@ class IssueQuery < Query joins(:status, :project). where(statement). includes(([:status, :project] + (options[:include] || [])).uniq). + references(([:status, :project] + (options[:include] || [])).uniq). where(options[:conditions]). order(order_option). joins(joins_for_order_statement(order_option.join(','))). limit(options[:limit]). offset(options[:offset]). - find_ids + pluck(:id) rescue ::ActiveRecord::StatementInvalid => e raise StatementInvalid.new(e.message) end @@ -380,7 +383,7 @@ class IssueQuery < Query limit(options[:limit]). offset(options[:offset]). preload(:details, :user, {:issue => [:project, :author, :tracker, :status]}). - all + to_a rescue ::ActiveRecord::StatementInvalid => e raise StatementInvalid.new(e.message) end @@ -392,7 +395,8 @@ class IssueQuery < Query where(project_statement). where(options[:conditions]). includes(:project). - all + references(:project). + to_a rescue ::ActiveRecord::StatementInvalid => e raise StatementInvalid.new(e.message) end @@ -411,7 +415,7 @@ class IssueQuery < Query groups = Group.givable operator = '!' # Override the operator since we want to find by assigned_to else - groups = Group.where(:id => value).all + groups = Group.where(:id => value).to_a end groups ||= [] @@ -431,7 +435,7 @@ class IssueQuery < Query " WHERE #{Member.table_name}.project_id = #{Issue.table_name}.project_id))" when "=", "!" role_cond = value.any? ? - "#{MemberRole.table_name}.role_id IN (" + value.collect{|val| "'#{connection.quote_string(val)}'"}.join(",") + ")" : + "#{MemberRole.table_name}.role_id IN (" + value.collect{|val| "'#{self.class.connection.quote_string(val)}'"}.join(",") + ")" : "1=0" sw = operator == "!" ? 'NOT' : '' @@ -443,7 +447,7 @@ class IssueQuery < Query def sql_for_is_private_field(field, operator, value) op = (operator == "=" ? 'IN' : 'NOT IN') - va = value.map {|v| v == '0' ? connection.quoted_false : connection.quoted_true}.uniq.join(',') + va = value.map {|v| v == '0' ? self.class.connection.quoted_false : self.class.connection.quoted_true}.uniq.join(',') "#{Issue.table_name}.is_private #{op} (#{va})" end @@ -462,14 +466,14 @@ class IssueQuery < Query sql = case operator when "*", "!*" op = (operator == "*" ? 'IN' : 'NOT IN') - "#{Issue.table_name}.id #{op} (SELECT DISTINCT #{IssueRelation.table_name}.#{join_column} FROM #{IssueRelation.table_name} WHERE #{IssueRelation.table_name}.relation_type = '#{connection.quote_string(relation_type)}')" + "#{Issue.table_name}.id #{op} (SELECT DISTINCT #{IssueRelation.table_name}.#{join_column} FROM #{IssueRelation.table_name} WHERE #{IssueRelation.table_name}.relation_type = '#{self.class.connection.quote_string(relation_type)}')" when "=", "!" op = (operator == "=" ? 'IN' : 'NOT IN') - "#{Issue.table_name}.id #{op} (SELECT DISTINCT #{IssueRelation.table_name}.#{join_column} FROM #{IssueRelation.table_name} WHERE #{IssueRelation.table_name}.relation_type = '#{connection.quote_string(relation_type)}' AND #{IssueRelation.table_name}.#{target_join_column} = #{value.first.to_i})" + "#{Issue.table_name}.id #{op} (SELECT DISTINCT #{IssueRelation.table_name}.#{join_column} FROM #{IssueRelation.table_name} WHERE #{IssueRelation.table_name}.relation_type = '#{self.class.connection.quote_string(relation_type)}' AND #{IssueRelation.table_name}.#{target_join_column} = #{value.first.to_i})" when "=p", "=!p", "!p" op = (operator == "!p" ? 'NOT IN' : 'IN') comp = (operator == "=!p" ? '<>' : '=') - "#{Issue.table_name}.id #{op} (SELECT DISTINCT #{IssueRelation.table_name}.#{join_column} FROM #{IssueRelation.table_name}, #{Issue.table_name} relissues WHERE #{IssueRelation.table_name}.relation_type = '#{connection.quote_string(relation_type)}' AND #{IssueRelation.table_name}.#{target_join_column} = relissues.id AND relissues.project_id #{comp} #{value.first.to_i})" + "#{Issue.table_name}.id #{op} (SELECT DISTINCT #{IssueRelation.table_name}.#{join_column} FROM #{IssueRelation.table_name}, #{Issue.table_name} relissues WHERE #{IssueRelation.table_name}.relation_type = '#{self.class.connection.quote_string(relation_type)}' AND #{IssueRelation.table_name}.#{target_join_column} = relissues.id AND relissues.project_id #{comp} #{value.first.to_i})" end if relation_options[:sym] == field && !options[:reverse] diff --git a/app/models/issue_status.rb b/app/models/issue_status.rb index d19ff50c5..ba0624a04 100644 --- a/app/models/issue_status.rb +++ b/app/models/issue_status.rb @@ -27,6 +27,7 @@ class IssueStatus < ActiveRecord::Base validates_uniqueness_of :name validates_length_of :name, :maximum => 30 validates_inclusion_of :default_done_ratio, :in => 0..100, :allow_nil => true + attr_protected :id scope :sorted, lambda { order("#{table_name}.position ASC") } scope :named, lambda {|arg| where("LOWER(#{table_name}.name) = LOWER(?)", arg.to_s.strip)} @@ -79,7 +80,7 @@ class IssueStatus < ActiveRecord::Base includes(:new_status). where(["role_id IN (:role_ids) AND tracker_id = :tracker_id AND (#{conditions})", {:role_ids => roles.collect(&:id), :tracker_id => tracker.id, :true => true, :false => false} - ]).all. + ]).to_a. map(&:new_status).compact.sort else [] diff --git a/app/models/journal.rb b/app/models/journal.rb index e3de2b38a..543da42b8 100644 --- a/app/models/journal.rb +++ b/app/models/journal.rb @@ -24,6 +24,7 @@ class Journal < ActiveRecord::Base belongs_to :user has_many :details, :class_name => "JournalDetail", :dependent => :delete_all attr_accessor :indice + attr_protected :id acts_as_event :title => Proc.new {|o| status = ((s = o.new_status) ? " (#{s})" : nil); "#{o.issue.tracker} ##{o.issue.id}#{status}: #{o.issue.subject}" }, :description => :notes, @@ -34,17 +35,18 @@ class Journal < ActiveRecord::Base acts_as_activity_provider :type => 'issues', :author_key => :user_id, - :find_options => {:include => [{:issue => :project}, :details, :user], - :conditions => "#{Journal.table_name}.journalized_type = 'Issue' AND" + - " (#{JournalDetail.table_name}.prop_key = 'status_id' OR #{Journal.table_name}.notes <> '')"} + :scope => preload({:issue => :project}, :user). + joins("LEFT OUTER JOIN #{JournalDetail.table_name} ON #{JournalDetail.table_name}.journal_id = #{Journal.table_name}.id"). + where("#{Journal.table_name}.journalized_type = 'Issue' AND" + + " (#{JournalDetail.table_name}.prop_key = 'status_id' OR #{Journal.table_name}.notes <> '')") before_create :split_private_notes after_create :send_notification scope :visible, lambda {|*args| user = args.shift || User.current - - includes(:issue => :project). + joins(:issue => :project). + references(:project). where(Issue.visible_condition(user, *args)). where("(#{Journal.table_name}.private_notes = ? OR (#{Project.allowed_to_condition(user, :view_private_notes, *args)}))", false) } diff --git a/app/models/journal_detail.rb b/app/models/journal_detail.rb index 2557ce87d..e67c19840 100644 --- a/app/models/journal_detail.rb +++ b/app/models/journal_detail.rb @@ -18,6 +18,7 @@ class JournalDetail < ActiveRecord::Base belongs_to :journal before_save :normalize_values + attr_protected :id def custom_field if property == 'cf' diff --git a/app/models/mail_handler.rb b/app/models/mail_handler.rb index 4aaa21c98..be737931c 100644 --- a/app/models/mail_handler.rb +++ b/app/models/mail_handler.rb @@ -42,7 +42,7 @@ class MailHandler < ActionMailer::Base @@handler_options[:no_notification] = (@@handler_options[:no_notification].to_s == '1') @@handler_options[:no_permission_check] = (@@handler_options[:no_permission_check].to_s == '1') - email.force_encoding('ASCII-8BIT') if email.respond_to?(:force_encoding) + email.force_encoding('ASCII-8BIT') super(email) end @@ -417,7 +417,7 @@ class MailHandler < ActionMailer::Base end parts.reject! do |part| - part.header[:content_disposition].try(:disposition_type) == 'attachment' + part.attachment? end @plain_text_body = parts.map do |p| diff --git a/app/models/member.rb b/app/models/member.rb index aa1d50cdf..8256d2e68 100644 --- a/app/models/member.rb +++ b/app/models/member.rb @@ -25,6 +25,7 @@ class Member < ActiveRecord::Base validates_presence_of :principal, :project validates_uniqueness_of :user_id, :scope => :project_id validate :validate_role + attr_protected :id before_destroy :set_issue_category_nil diff --git a/app/models/member_role.rb b/app/models/member_role.rb index 74d4c631f..038509026 100644 --- a/app/models/member_role.rb +++ b/app/models/member_role.rb @@ -26,6 +26,7 @@ class MemberRole < ActiveRecord::Base validates_presence_of :role validate :validate_role_member + attr_protected :id def validate_role_member errors.add :role_id, :invalid if role && !role.member? diff --git a/app/models/message.rb b/app/models/message.rb index 576be4763..028a3eb55 100644 --- a/app/models/message.rb +++ b/app/models/message.rb @@ -22,9 +22,10 @@ class Message < ActiveRecord::Base acts_as_tree :counter_cache => :replies_count, :order => "#{Message.table_name}.created_on ASC" acts_as_attachable belongs_to :last_reply, :class_name => 'Message', :foreign_key => 'last_reply_id' + attr_protected :id acts_as_searchable :columns => ['subject', 'content'], - :include => {:board => :project}, + :scope => preload(:board => :project), :project_key => "#{Board.table_name}.project_id", :date_column => "#{table_name}.created_on" acts_as_event :title => Proc.new {|o| "#{o.board.name}: #{o.subject}"}, @@ -34,7 +35,7 @@ class Message < ActiveRecord::Base :url => Proc.new {|o| {:controller => 'messages', :action => 'show', :board_id => o.board_id}.merge(o.parent_id.nil? ? {:id => o.id} : {:id => o.parent_id, :r => o.id, :anchor => "message-#{o.id}"})} - acts_as_activity_provider :find_options => {:include => [{:board => :project}, :author]}, + acts_as_activity_provider :scope => preload({:board => :project}, :author), :author_key => :author_id acts_as_watchable @@ -48,7 +49,9 @@ class Message < ActiveRecord::Base after_create :send_notification scope :visible, lambda {|*args| - includes(:board => :project).where(Project.allowed_to_condition(args.shift || User.current, :view_messages, *args)) + joins(:board => :project). + references(:board => :project). + where(Project.allowed_to_condition(args.shift || User.current, :view_messages, *args)) } safe_attributes 'subject', 'content' diff --git a/app/models/news.rb b/app/models/news.rb index b86e3f63d..baaa92fba 100644 --- a/app/models/news.rb +++ b/app/models/news.rb @@ -19,16 +19,18 @@ class News < ActiveRecord::Base include Redmine::SafeAttributes belongs_to :project belongs_to :author, :class_name => 'User', :foreign_key => 'author_id' - has_many :comments, :as => :commented, :dependent => :delete_all, :order => "created_on" + has_many :comments, lambda {order("created_on")}, :as => :commented, :dependent => :delete_all validates_presence_of :title, :description validates_length_of :title, :maximum => 60 validates_length_of :summary, :maximum => 255 + attr_protected :id acts_as_attachable :delete_permission => :manage_news - acts_as_searchable :columns => ['title', 'summary', "#{table_name}.description"], :include => :project + acts_as_searchable :columns => ['title', 'summary', "#{table_name}.description"], + :scope => preload(:project) acts_as_event :url => Proc.new {|o| {:controller => 'news', :action => 'show', :id => o.id}} - acts_as_activity_provider :find_options => {:include => [:project, :author]}, + acts_as_activity_provider :scope => preload(:project, :author), :author_key => :author_id acts_as_watchable @@ -36,7 +38,9 @@ class News < ActiveRecord::Base after_create :send_notification scope :visible, lambda {|*args| - includes(:project).where(Project.allowed_to_condition(args.shift || User.current, :view_news, *args)) + joins(:project). + references([:author, :project]). + where(Project.allowed_to_condition(args.shift || User.current, :view_news, *args)) } safe_attributes 'title', 'summary', 'description' @@ -68,7 +72,7 @@ class News < ActiveRecord::Base # returns latest news for projects visible by user def self.latest(user = User.current, count = 5) - visible(user).includes([:author, :project]).order("#{News.table_name}.created_on DESC").limit(count).all + visible(user).joins([:author, :project]).order("#{News.table_name}.created_on DESC").limit(count).to_a end private diff --git a/app/models/principal.rb b/app/models/principal.rb index 1bbbbe88e..d10241b3f 100644 --- a/app/models/principal.rb +++ b/app/models/principal.rb @@ -25,11 +25,13 @@ class Principal < ActiveRecord::Base STATUS_LOCKED = 3 has_many :members, :foreign_key => 'user_id', :dependent => :destroy - has_many :memberships, :class_name => 'Member', - :foreign_key => 'user_id', - :include => [:project, :roles], - :conditions => "#{Project.table_name}.status<>#{Project::STATUS_ARCHIVED}", - :order => "#{Project.table_name}.name" + has_many :memberships, + lambda {preload(:project, :roles). + joins(:project). + where("#{Project.table_name}.status<>#{Project::STATUS_ARCHIVED}"). + order("#{Project.table_name}.name")}, + :class_name => 'Member', + :foreign_key => 'user_id' has_many :projects, :through => :memberships has_many :issue_categories, :foreign_key => 'assigned_to_id', :dependent => :nullify @@ -56,8 +58,8 @@ class Principal < ActiveRecord::Base # Principals that are members of a collection of projects scope :member_of, lambda {|projects| - projects = [projects] unless projects.is_a?(Array) - if projects.empty? + projects = [projects] if projects.is_a?(Project) + if projects.blank? where("1=0") else ids = projects.map(&:id) diff --git a/app/models/project.rb b/app/models/project.rb index 6a428b209..c2b8af134 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -28,31 +28,35 @@ class Project < ActiveRecord::Base # Specific overridden Activities has_many :time_entry_activities - has_many :members, :include => [:principal, :roles], :conditions => "#{Principal.table_name}.type='User' AND #{Principal.table_name}.status=#{Principal::STATUS_ACTIVE}" + has_many :members, + lambda { joins(:principal, :roles). + references(:principal, :roles). + where("#{Principal.table_name}.type='User' AND #{Principal.table_name}.status=#{Principal::STATUS_ACTIVE}") } has_many :memberships, :class_name => 'Member' - has_many :member_principals, :class_name => 'Member', - :include => :principal, - :conditions => "#{Principal.table_name}.status=#{Principal::STATUS_ACTIVE}" - + has_many :member_principals, + lambda { joins(:principal). + references(:principal). + where("#{Principal.table_name}.status=#{Principal::STATUS_ACTIVE}")}, + :class_name => 'Member' has_many :enabled_modules, :dependent => :delete_all - has_and_belongs_to_many :trackers, :order => "#{Tracker.table_name}.position" - has_many :issues, :dependent => :destroy, :include => [:status, :tracker] + has_and_belongs_to_many :trackers, lambda {order("#{Tracker.table_name}.position")} + has_many :issues, :dependent => :destroy has_many :issue_changes, :through => :issues, :source => :journals - has_many :versions, :dependent => :destroy, :order => "#{Version.table_name}.effective_date DESC, #{Version.table_name}.name DESC" + has_many :versions, lambda {order("#{Version.table_name}.effective_date DESC, #{Version.table_name}.name DESC")}, :dependent => :destroy has_many :time_entries, :dependent => :destroy has_many :queries, :class_name => 'IssueQuery', :dependent => :delete_all has_many :documents, :dependent => :destroy - has_many :news, :dependent => :destroy, :include => :author - has_many :issue_categories, :dependent => :delete_all, :order => "#{IssueCategory.table_name}.name" - has_many :boards, :dependent => :destroy, :order => "position ASC" - has_one :repository, :conditions => ["is_default = ?", true] + has_many :news, lambda {includes(:author)}, :dependent => :destroy + has_many :issue_categories, lambda {order("#{IssueCategory.table_name}.name")}, :dependent => :delete_all + has_many :boards, lambda {order("position ASC")}, :dependent => :destroy + has_one :repository, lambda {where(["is_default = ?", true])} has_many :repositories, :dependent => :destroy has_many :changesets, :through => :repository has_one :wiki, :dependent => :destroy # Custom field for the project issues has_and_belongs_to_many :issue_custom_fields, + lambda {order("#{CustomField.table_name}.position")}, :class_name => 'IssueCustomField', - :order => "#{CustomField.table_name}.position", :join_table => "#{table_name_prefix}custom_fields_projects#{table_name_suffix}", :association_foreign_key => 'custom_field_id' @@ -126,9 +130,9 @@ class Project < ActiveRecord::Base if !initialized.key?('trackers') && !initialized.key?('tracker_ids') default = Setting.default_projects_tracker_ids if default.is_a?(Array) - self.trackers = Tracker.where(:id => default.map(&:to_i)).sorted.all + self.trackers = Tracker.where(:id => default.map(&:to_i)).sorted.to_a else - self.trackers = Tracker.sorted.all + self.trackers = Tracker.sorted.to_a end end end @@ -144,7 +148,7 @@ class Project < ActiveRecord::Base # returns latest created projects # non public projects will be returned only if user is a member of those def self.latest(user=nil, count=5) - visible(user).limit(count).order("created_on DESC").all + visible(user).limit(count).order("created_on DESC").to_a end # Returns true if the project is visible to +user+ or to the current user. @@ -212,9 +216,9 @@ class Project < ActiveRecord::Base end def override_roles(role) - @override_members ||= memberships.where(:user_id => [GroupAnonymous.instance_id, GroupNonMember.instance_id]).all - member = @override_members.detect {|m| role.anonymous? ^ (m.user_id == GroupNonMember.instance_id)} - member ? member.roles : [role] + group_class = role.anonymous? ? GroupAnonymous : GroupNonMember + member = member_principals.where("#{Principal.table_name}.type = ?", group_class.name).first + member ? member.roles.to_a : [role] end def principals @@ -364,7 +368,7 @@ class Project < ActiveRecord::Base # by the current user def allowed_parents return @allowed_parents if @allowed_parents - @allowed_parents = Project.where(Project.allowed_to_condition(User.current, :add_subprojects)).all + @allowed_parents = Project.where(Project.allowed_to_condition(User.current, :add_subprojects)).to_a @allowed_parents = @allowed_parents - self_and_descendants if User.current.allowed_to?(:add_project, nil, :global => true) || (!new_record? && parent.nil?) @allowed_parents << nil @@ -435,11 +439,12 @@ class Project < ActiveRecord::Base @rolled_up_trackers ||= Tracker. joins(:projects). + references(:project). joins("JOIN #{EnabledModule.table_name} ON #{EnabledModule.table_name}.project_id = #{Project.table_name}.id AND #{EnabledModule.table_name}.name = 'issue_tracking'"). select("DISTINCT #{Tracker.table_name}.*"). where("#{Project.table_name}.lft >= ? AND #{Project.table_name}.rgt <= ? AND #{Project.table_name}.status <> #{STATUS_ARCHIVED}", lft, rgt). sorted. - all + to_a end # Closes open and locked project versions that are completed @@ -457,7 +462,8 @@ class Project < ActiveRecord::Base def rolled_up_versions @rolled_up_versions ||= Version. - includes(:project). + joins(:project). + references(:project). where("#{Project.table_name}.lft >= ? AND #{Project.table_name}.rgt <= ? AND #{Project.table_name}.status <> ?", lft, rgt, STATUS_ARCHIVED) end @@ -465,13 +471,17 @@ class Project < ActiveRecord::Base def shared_versions if new_record? Version. - includes(:project). + joins(:project). + references(:project). + preload(:project). where("#{Project.table_name}.status <> ? AND #{Version.table_name}.sharing = 'system'", STATUS_ARCHIVED) else @shared_versions ||= begin r = root? ? self : root Version. - includes(:project). + joins(:project). + references(:project). + preload(:project). where("#{Project.table_name}.id = #{id}" + " OR (#{Project.table_name}.status <> #{Project::STATUS_ARCHIVED} AND (" + " #{Version.table_name}.sharing = 'system'" + @@ -497,7 +507,7 @@ class Project < ActiveRecord::Base # Deletes all project's members def delete_all_members me, mr = Member.table_name, MemberRole.table_name - connection.delete("DELETE FROM #{mr} WHERE #{mr}.member_id IN (SELECT #{me}.id FROM #{me} WHERE #{me}.project_id = #{id})") + self.class.connection.delete("DELETE FROM #{mr} WHERE #{mr}.member_id IN (SELECT #{me}.id FROM #{me} WHERE #{me}.project_id = #{id})") Member.delete_all(['project_id = ?', id]) end @@ -728,7 +738,7 @@ class Project < ActiveRecord::Base project = project.is_a?(Project) ? project : Project.find(project) to_be_copied = %w(wiki versions issue_categories issues members queries boards) - to_be_copied = to_be_copied & options[:only].to_a unless options[:only].nil? + to_be_copied = to_be_copied & Array.wrap(options[:only]) unless options[:only].nil? Project.transaction do if save @@ -740,6 +750,7 @@ class Project < ActiveRecord::Base save end end + true end # Returns a new unsaved Project instance with attributes copied from +project+ @@ -958,11 +969,10 @@ class Project < ActiveRecord::Base def copy_queries(project) project.queries.each do |query| new_query = IssueQuery.new - new_query.attributes = query.attributes.dup.except("id", "project_id", "sort_criteria", "user_id", "type") + new_query.attributes = query.attributes.dup.except("id", "project_id", "sort_criteria") new_query.sort_criteria = query.sort_criteria if query.sort_criteria new_query.project = self new_query.user_id = query.user_id - new_query.role_ids = query.role_ids if query.visibility == IssueQuery::VISIBILITY_ROLES self.queries << new_query end end diff --git a/app/models/query.rb b/app/models/query.rb index 9ef002c6e..a4d34d1e4 100644 --- a/app/models/query.rb +++ b/app/models/query.rb @@ -288,7 +288,7 @@ class Query < ActiveRecord::Base end def trackers - @trackers ||= project.nil? ? Tracker.sorted.all : project.rolled_up_trackers + @trackers ||= project.nil? ? Tracker.sorted.to_a : project.rolled_up_trackers end # Returns a hash of localized labels for all filter operators @@ -306,7 +306,7 @@ class Query < ActiveRecord::Base end def all_projects - @all_projects ||= Project.visible.all + @all_projects ||= Project.visible.to_a end def all_projects_values @@ -655,7 +655,7 @@ class Query < ActiveRecord::Base sql = "#{db_table}.#{db_field} BETWEEN #{value.first.to_f - 1e-5} AND #{value.first.to_f + 1e-5}" end else - sql = "#{db_table}.#{db_field} IN (" + value.collect{|val| "'#{connection.quote_string(val)}'"}.join(",") + ")" + sql = "#{db_table}.#{db_field} IN (" + value.collect{|val| "'#{self.class.connection.quote_string(val)}'"}.join(",") + ")" end else # IN an empty set @@ -663,7 +663,7 @@ class Query < ActiveRecord::Base end when "!" if value.any? - sql = "(#{db_table}.#{db_field} IS NULL OR #{db_table}.#{db_field} NOT IN (" + value.collect{|val| "'#{connection.quote_string(val)}'"}.join(",") + "))" + sql = "(#{db_table}.#{db_field} IS NULL OR #{db_table}.#{db_field} NOT IN (" + value.collect{|val| "'#{self.class.connection.quote_string(val)}'"}.join(",") + "))" else # NOT IN an empty set sql = "1=1" @@ -705,9 +705,9 @@ class Query < ActiveRecord::Base end end when "o" - sql = "#{queried_table_name}.status_id IN (SELECT id FROM #{IssueStatus.table_name} WHERE is_closed=#{connection.quoted_false})" if field == "status_id" + sql = "#{queried_table_name}.status_id IN (SELECT id FROM #{IssueStatus.table_name} WHERE is_closed=#{self.class.connection.quoted_false})" if field == "status_id" when "c" - sql = "#{queried_table_name}.status_id IN (SELECT id FROM #{IssueStatus.table_name} WHERE is_closed=#{connection.quoted_true})" if field == "status_id" + sql = "#{queried_table_name}.status_id IN (SELECT id FROM #{IssueStatus.table_name} WHERE is_closed=#{self.class.connection.quoted_true})" if field == "status_id" when "><t-" # between today - n days and today sql = relative_date_clause(db_table, db_field, - value.first.to_i, 0) @@ -769,9 +769,9 @@ class Query < ActiveRecord::Base date = Date.today sql = date_clause(db_table, db_field, date.beginning_of_year, date.end_of_year) when "~" - sql = "LOWER(#{db_table}.#{db_field}) LIKE '%#{connection.quote_string(value.first.to_s.downcase)}%'" + sql = "LOWER(#{db_table}.#{db_field}) LIKE '%#{self.class.connection.quote_string(value.first.to_s.downcase)}%'" when "!~" - sql = "LOWER(#{db_table}.#{db_field}) NOT LIKE '%#{connection.quote_string(value.first.to_s.downcase)}%'" + sql = "LOWER(#{db_table}.#{db_field}) NOT LIKE '%#{self.class.connection.quote_string(value.first.to_s.downcase)}%'" else raise "Unknown query operator #{operator}" end @@ -834,7 +834,7 @@ class Query < ActiveRecord::Base if self.class.default_timezone == :utc from = from.utc end - s << ("#{table}.#{field} > '%s'" % [connection.quoted_date(from)]) + s << ("#{table}.#{field} > '%s'" % [self.class.connection.quoted_date(from)]) end if to if to.is_a?(Date) @@ -843,7 +843,7 @@ class Query < ActiveRecord::Base if self.class.default_timezone == :utc to = to.utc end - s << ("#{table}.#{field} <= '%s'" % [connection.quoted_date(to)]) + s << ("#{table}.#{field} <= '%s'" % [self.class.connection.quoted_date(to)]) end s.join(' AND ') end diff --git a/app/models/repository.rb b/app/models/repository.rb index 25b0e1da8..1cab86bd1 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -25,7 +25,7 @@ class Repository < ActiveRecord::Base IDENTIFIER_MAX_LENGTH = 255 belongs_to :project - has_many :changesets, :order => "#{Changeset.table_name}.committed_on DESC, #{Changeset.table_name}.id DESC" + has_many :changesets, lambda{order("#{Changeset.table_name}.committed_on DESC, #{Changeset.table_name}.id DESC")} has_many :filechanges, :class_name => 'Change', :through => :changesets serialize :extra_info @@ -45,6 +45,7 @@ class Repository < ActiveRecord::Base validates_format_of :identifier, :with => /\A(?!\d+$)[a-z0-9\-_]*\z/, :allow_blank => true # Checks if the SCM is enabled when creating a repository validate :repo_create_validation, :on => :create + attr_protected :id safe_attributes 'identifier', 'login', @@ -264,7 +265,7 @@ class Repository < ActiveRecord::Base reorder("#{Changeset.table_name}.committed_on DESC, #{Changeset.table_name}.id DESC"). limit(limit). preload(:user). - all + to_a else filechanges. where("path = ?", path.with_leading_slash). @@ -313,7 +314,8 @@ class Repository < ActiveRecord::Base return @found_committer_users[committer] if @found_committer_users.has_key?(committer) user = nil - c = changesets.where(:committer => committer).includes(:user).first + c = changesets.where(:committer => committer). + includes(:user).references(:user).first if c && c.user user = c.user elsif committer.strip =~ /^([^<]+)(<(.*)>)?$/ @@ -484,10 +486,10 @@ class Repository < ActiveRecord::Base ci = "#{table_name_prefix}changesets_issues#{table_name_suffix}" cp = "#{table_name_prefix}changeset_parents#{table_name_suffix}" - connection.delete("DELETE FROM #{ch} WHERE #{ch}.changeset_id IN (SELECT #{cs}.id FROM #{cs} WHERE #{cs}.repository_id = #{id})") - connection.delete("DELETE FROM #{ci} WHERE #{ci}.changeset_id IN (SELECT #{cs}.id FROM #{cs} WHERE #{cs}.repository_id = #{id})") - connection.delete("DELETE FROM #{cp} WHERE #{cp}.changeset_id IN (SELECT #{cs}.id FROM #{cs} WHERE #{cs}.repository_id = #{id})") - connection.delete("DELETE FROM #{cs} WHERE #{cs}.repository_id = #{id}") + self.class.connection.delete("DELETE FROM #{ch} WHERE #{ch}.changeset_id IN (SELECT #{cs}.id FROM #{cs} WHERE #{cs}.repository_id = #{id})") + self.class.connection.delete("DELETE FROM #{ci} WHERE #{ci}.changeset_id IN (SELECT #{cs}.id FROM #{cs} WHERE #{cs}.repository_id = #{id})") + self.class.connection.delete("DELETE FROM #{cp} WHERE #{cp}.changeset_id IN (SELECT #{cs}.id FROM #{cs} WHERE #{cs}.repository_id = #{id})") + self.class.connection.delete("DELETE FROM #{cs} WHERE #{cs}.repository_id = #{id}") clear_extra_info_of_changesets end diff --git a/app/models/repository/cvs.rb b/app/models/repository/cvs.rb index 09d79c4fb..abc408304 100644 --- a/app/models/repository/cvs.rb +++ b/app/models/repository/cvs.rb @@ -199,7 +199,7 @@ class Repository::Cvs < Repository # Need to retrieve existing revision numbers to sort them as integers sql = "SELECT revision FROM #{Changeset.table_name} " sql << "WHERE repository_id = #{id} AND revision NOT LIKE 'tmp%'" - @current_revision_number ||= (connection.select_values(sql).collect(&:to_i).max || 0) + @current_revision_number ||= (self.class.connection.select_values(sql).collect(&:to_i).max || 0) @current_revision_number += 1 end end diff --git a/app/models/repository/git.rb b/app/models/repository/git.rb index c51a7e58a..978944efc 100644 --- a/app/models/repository/git.rb +++ b/app/models/repository/git.rb @@ -241,7 +241,7 @@ class Repository::Git < Repository def latest_changesets(path,rev,limit=10) revisions = scm.revisions(path, nil, rev, :limit => limit, :all => false) return [] if revisions.nil? || revisions.empty? - changesets.where(:scmid => revisions.map {|c| c.scmid}).all + changesets.where(:scmid => revisions.map {|c| c.scmid}).to_a end def clear_extra_info_of_changesets diff --git a/app/models/repository/mercurial.rb b/app/models/repository/mercurial.rb index abe1dfb70..81dd24d00 100644 --- a/app/models/repository/mercurial.rb +++ b/app/models/repository/mercurial.rb @@ -20,7 +20,7 @@ require 'redmine/scm/adapters/mercurial_adapter' class Repository::Mercurial < Repository # sort changesets by revision number has_many :changesets, - :order => "#{Changeset.table_name}.id DESC", + lambda {order("#{Changeset.table_name}.id DESC")}, :foreign_key => 'repository_id' attr_protected :root_url @@ -117,9 +117,10 @@ class Repository::Mercurial < Repository changesets. includes(:user). where(latest_changesets_cond(path, rev, limit)). + references(:user). limit(limit). order("#{Changeset.table_name}.id DESC"). - all + to_a end def is_short_id_in_db? diff --git a/app/models/repository/subversion.rb b/app/models/repository/subversion.rb index 532c1f3a2..1659b77f8 100644 --- a/app/models/repository/subversion.rb +++ b/app/models/repository/subversion.rb @@ -42,7 +42,7 @@ class Repository::Subversion < Repository revisions = scm.revisions(path, rev, nil, :limit => limit) if revisions identifiers = revisions.collect(&:identifier).compact - changesets.where(:revision => identifiers).reorder("committed_on DESC").includes(:repository, :user).all + changesets.where(:revision => identifiers).reorder("committed_on DESC").includes(:repository, :user).to_a else [] end diff --git a/app/models/role.rb b/app/models/role.rb index 10977612d..efd9a334d 100644 --- a/app/models/role.rb +++ b/app/models/role.rb @@ -166,7 +166,7 @@ class Role < ActiveRecord::Base # Find all the roles that can be given to a project member def self.find_all_givable - Role.givable.all + Role.givable.to_a end # Return the builtin 'non member' role. If the role doesn't exist, diff --git a/app/models/setting.rb b/app/models/setting.rb index 532e9d44d..3881f90f1 100644 --- a/app/models/setting.rb +++ b/app/models/setting.rb @@ -86,6 +86,7 @@ class Setting < ActiveRecord::Base validates_numericality_of :value, :only_integer => true, :if => Proc.new { |setting| (s = @@available_settings[setting.name]) && s['format'] == 'int' } + attr_protected :id # Hash used to cache setting values @cached_settings = {} @@ -142,6 +143,7 @@ END_SRC def self.set_from_params(name, params) params = params.dup params.delete_if {|v| v.blank? } if params.is_a?(Array) + params.symbolize_keys! if params.is_a?(Hash) m = "#{name}_from_params" if respond_to? m diff --git a/app/models/time_entry.rb b/app/models/time_entry.rb index 662070840..8738668cc 100644 --- a/app/models/time_entry.rb +++ b/app/models/time_entry.rb @@ -35,7 +35,7 @@ class TimeEntry < ActiveRecord::Base acts_as_activity_provider :timestamp => "#{table_name}.created_on", :author_key => :user_id, - :find_options => {:include => :project} + :scope => preload(:project) validates_presence_of :user_id, :activity_id, :project_id, :hours, :spent_on validates_numericality_of :hours, :allow_nil => true, :message => :invalid @@ -45,13 +45,19 @@ class TimeEntry < ActiveRecord::Base validate :validate_time_entry scope :visible, lambda {|*args| - includes(:project).where(Project.allowed_to_condition(args.shift || User.current, :view_time_entries, *args)) + joins(:project). + references(:project). + where(Project.allowed_to_condition(args.shift || User.current, :view_time_entries, *args)) } scope :on_issue, lambda {|issue| - includes(:issue).where("#{Issue.table_name}.root_id = #{issue.root_id} AND #{Issue.table_name}.lft >= #{issue.lft} AND #{Issue.table_name}.rgt <= #{issue.rgt}") + joins(:issue). + references(:issue). + where("#{Issue.table_name}.root_id = #{issue.root_id} AND #{Issue.table_name}.lft >= #{issue.lft} AND #{Issue.table_name}.rgt <= #{issue.rgt}") } scope :on_project, lambda {|project, include_subprojects| - includes(:project).where(project.project_condition(include_subprojects)) + joins(:project). + references(:project). + where(project.project_condition(include_subprojects)) } scope :spent_between, lambda {|from, to| if from && to diff --git a/app/models/time_entry_query.rb b/app/models/time_entry_query.rb index bd2eef398..05c39f55e 100644 --- a/app/models/time_entry_query.rb +++ b/app/models/time_entry_query.rb @@ -42,7 +42,7 @@ class TimeEntryQuery < Query if project principals += project.principals.sort unless project.leaf? - subprojects = project.descendants.visible.all + subprojects = project.descendants.visible.to_a if subprojects.any? add_available_filter "subproject_id", :type => :list_subprojects, @@ -109,7 +109,8 @@ class TimeEntryQuery < Query where(statement). order(order_option). joins(joins_for_order_statement(order_option.join(','))). - includes(:activity) + includes(:activity). + references(:activity) end def sql_for_activity_id_field(field, operator, value) diff --git a/app/models/token.rb b/app/models/token.rb index b1d2d2905..0f3751030 100644 --- a/app/models/token.rb +++ b/app/models/token.rb @@ -18,6 +18,7 @@ class Token < ActiveRecord::Base belongs_to :user validates_uniqueness_of :value + attr_protected :id before_create :delete_previous_tokens, :generate_new_token diff --git a/app/models/tracker.rb b/app/models/tracker.rb index 20ba84527..b4f22c811 100644 --- a/app/models/tracker.rb +++ b/app/models/tracker.rb @@ -63,7 +63,7 @@ class Tracker < ActiveRecord::Base connection.select_rows("SELECT DISTINCT old_status_id, new_status_id FROM #{WorkflowTransition.table_name} WHERE tracker_id = #{id} AND type = 'WorkflowTransition'"). flatten. uniq - @issue_statuses = IssueStatus.where(:id => ids).all.sort + @issue_statuses = IssueStatus.where(:id => ids).to_a.sort end def disabled_core_fields @@ -92,7 +92,7 @@ class Tracker < ActiveRecord::Base # Returns the fields that are disabled for all the given trackers def self.disabled_core_fields(trackers) if trackers.present? - trackers.uniq.map(&:disabled_core_fields).reduce(:&) + trackers.map(&:disabled_core_fields).reduce(:&) else [] end diff --git a/app/models/user.rb b/app/models/user.rb index d8590f47c..d86627e85 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -79,8 +79,8 @@ class User < Principal :after_remove => Proc.new {|user, group| group.user_removed(user)} has_many :changesets, :dependent => :nullify has_one :preference, :dependent => :destroy, :class_name => 'UserPreference' - has_one :rss_token, :class_name => 'Token', :conditions => "action='feeds'" - has_one :api_token, :class_name => 'Token', :conditions => "action='api'" + has_one :rss_token, lambda {where "action='feeds'"}, :class_name => 'Token' + has_one :api_token, lambda {where "action='api'"}, :class_name => 'Token' belongs_to :auth_source scope :logged, lambda { where("#{User.table_name}.status <> #{STATUS_ANONYMOUS}") } @@ -105,9 +105,13 @@ class User < Principal validates_length_of :firstname, :lastname, :maximum => 30 validates_format_of :mail, :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i, :allow_blank => true validates_length_of :mail, :maximum => MAIL_LENGTH_LIMIT, :allow_nil => true - validates_confirmation_of :password, :allow_nil => true validates_inclusion_of :mail_notification, :in => MAIL_NOTIFICATION_OPTIONS.collect(&:first), :allow_blank => true validate :validate_password_length + validate do + if password_confirmation && password != password_confirmation + errors.add(:password, :confirmation) + end + end before_create :set_mail_notification before_save :generate_password_if_needed, :update_hashed_password @@ -151,6 +155,15 @@ class User < Principal write_attribute(:mail, arg.to_s.strip) end + def self.find_or_initialize_by_identity_url(url) + user = where(:identity_url => url).first + unless user + user = User.new + user.identity_url = url + end + user + end + def identity_url=(url) if url.blank? write_attribute(:identity_url, '') @@ -496,10 +509,12 @@ class User < Principal hash = Hash.new([]) - members = Member.joins(:project). + group_class = anonymous? ? GroupAnonymous : GroupNonMember + members = Member.joins(:project, :principal). where("#{Project.table_name}.status <> 9"). - where("#{Member.table_name}.user_id = ? OR (#{Project.table_name}.is_public = ? AND #{Member.table_name}.user_id = ?)", self.id, true, Group.builtin_id(self)). - preload(:project, :roles) + where("#{Member.table_name}.user_id = ? OR (#{Project.table_name}.is_public = ? AND #{Principal.table_name}.type = ?)", self.id, true, group_class.name). + preload(:project, :roles). + to_a members.reject! {|member| member.user_id != id && project_ids.include?(member.project_id)} members.each do |member| @@ -558,6 +573,8 @@ class User < Principal # Authorize if user is authorized on every element of the array context.map {|project| allowed_to?(action, project, options, &block)}.reduce(:&) end + elsif context + raise ArgumentError.new("#allowed_to? context argument must be a Project, an Array of projects or nil") elsif options[:global] # Admin users are always authorized return true if admin? @@ -710,17 +727,17 @@ class User < Principal return if self.id.nil? substitute = User.anonymous - Attachment.where(['author_id = ?', id]).update_all(['author_id = ?', substitute.id]) + Attachment.where(['author_id = ?', id]).update_all(['author_id = ?', substitute.id]) Comment.where(['author_id = ?', id]).update_all(['author_id = ?', substitute.id]) Issue.where(['author_id = ?', id]).update_all(['author_id = ?', substitute.id]) Issue.where(['assigned_to_id = ?', id]).update_all('assigned_to_id = NULL') - Journal.where(['user_id = ?', id]).update_all(['user_id = ?', substitute.id]) + Journal.where(['user_id = ?', id]).update_all(['user_id = ?', substitute.id]) JournalDetail. where(["property = 'attr' AND prop_key = 'assigned_to_id' AND old_value = ?", id.to_s]). update_all(['old_value = ?', substitute.id.to_s]) JournalDetail. where(["property = 'attr' AND prop_key = 'assigned_to_id' AND value = ?", id.to_s]). - update_all(['value = ?', substitute.id.to_s]) + update_all(['value = ?', substitute.id.to_s]) Message.where(['author_id = ?', id]).update_all(['author_id = ?', substitute.id]) News.where(['author_id = ?', id]).update_all(['author_id = ?', substitute.id]) # Remove private queries and keep public ones diff --git a/app/models/version.rb b/app/models/version.rb index 1d06360ef..45c7c25a6 100644 --- a/app/models/version.rb +++ b/app/models/version.rb @@ -33,11 +33,14 @@ class Version < ActiveRecord::Base validates :effective_date, :date => true validates_inclusion_of :status, :in => VERSION_STATUSES validates_inclusion_of :sharing, :in => VERSION_SHARINGS + attr_protected :id scope :named, lambda {|arg| where("LOWER(#{table_name}.name) = LOWER(?)", arg.to_s.strip)} scope :open, lambda { where(:status => 'open') } scope :visible, lambda {|*args| - includes(:project).where(Project.allowed_to_condition(args.first || User.current, :view_issues)) + joins(:project). + references(:project). + where(Project.allowed_to_condition(args.first || User.current, :view_issues)) } safe_attributes 'name', @@ -230,11 +233,6 @@ class Version < ActiveRecord::Base end end - # Returns true if the version is shared, otherwise false - def shared? - sharing != 'none' - end - private def load_issue_counts diff --git a/app/models/watcher.rb b/app/models/watcher.rb index 1f42de86f..9981bea1c 100644 --- a/app/models/watcher.rb +++ b/app/models/watcher.rb @@ -22,6 +22,7 @@ class Watcher < ActiveRecord::Base validates_presence_of :user validates_uniqueness_of :user_id, :scope => [:watchable_type, :watchable_id] validate :validate_user + attr_protected :id # Returns true if at least one object among objects is watched by user def self.any_watched?(objects, user) diff --git a/app/models/wiki.rb b/app/models/wiki.rb index 45a22fda1..b1ce29743 100644 --- a/app/models/wiki.rb +++ b/app/models/wiki.rb @@ -18,13 +18,14 @@ class Wiki < ActiveRecord::Base include Redmine::SafeAttributes belongs_to :project - has_many :pages, :class_name => 'WikiPage', :dependent => :destroy, :order => 'title' + has_many :pages, lambda {order('title')}, :class_name => 'WikiPage', :dependent => :destroy has_many :redirects, :class_name => 'WikiRedirect', :dependent => :delete_all acts_as_watchable validates_presence_of :start_page validates_format_of :start_page, :with => /\A[^,\.\/\?\;\|\:]*\z/ + attr_protected :id safe_attributes 'start_page' diff --git a/app/models/wiki_content.rb b/app/models/wiki_content.rb index 415ba9aca..3eac92688 100644 --- a/app/models/wiki_content.rb +++ b/app/models/wiki_content.rb @@ -23,6 +23,7 @@ class WikiContent < ActiveRecord::Base belongs_to :author, :class_name => 'User', :foreign_key => 'author_id' validates_presence_of :text validates_length_of :comments, :maximum => 255, :allow_nil => true + attr_protected :id acts_as_versioned @@ -68,13 +69,13 @@ class WikiContent < ActiveRecord::Base :timestamp => "#{WikiContent.versioned_table_name}.updated_on", :author_key => "#{WikiContent.versioned_table_name}.author_id", :permission => :view_wiki_edits, - :find_options => {:select => "#{WikiContent.versioned_table_name}.updated_on, #{WikiContent.versioned_table_name}.comments, " + - "#{WikiContent.versioned_table_name}.#{WikiContent.version_column}, #{WikiPage.table_name}.title, " + - "#{WikiContent.versioned_table_name}.page_id, #{WikiContent.versioned_table_name}.author_id, " + - "#{WikiContent.versioned_table_name}.id", - :joins => "LEFT JOIN #{WikiPage.table_name} ON #{WikiPage.table_name}.id = #{WikiContent.versioned_table_name}.page_id " + - "LEFT JOIN #{Wiki.table_name} ON #{Wiki.table_name}.id = #{WikiPage.table_name}.wiki_id " + - "LEFT JOIN #{Project.table_name} ON #{Project.table_name}.id = #{Wiki.table_name}.project_id"} + :scope => select("#{WikiContent.versioned_table_name}.updated_on, #{WikiContent.versioned_table_name}.comments, " + + "#{WikiContent.versioned_table_name}.#{WikiContent.version_column}, #{WikiPage.table_name}.title, " + + "#{WikiContent.versioned_table_name}.page_id, #{WikiContent.versioned_table_name}.author_id, " + + "#{WikiContent.versioned_table_name}.id"). + joins("LEFT JOIN #{WikiPage.table_name} ON #{WikiPage.table_name}.id = #{WikiContent.versioned_table_name}.page_id " + + "LEFT JOIN #{Wiki.table_name} ON #{Wiki.table_name}.id = #{WikiPage.table_name}.wiki_id " + + "LEFT JOIN #{Project.table_name} ON #{Project.table_name}.id = #{Wiki.table_name}.project_id") after_destroy :page_update_after_destroy @@ -104,7 +105,7 @@ class WikiContent < ActiveRecord::Base # uncompressed data data end - str.force_encoding("UTF-8") if str.respond_to?(:force_encoding) + str.force_encoding("UTF-8") str end end diff --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb index fc56d9d6b..8aed835ad 100644 --- a/app/models/wiki_page.rb +++ b/app/models/wiki_page.rb @@ -33,7 +33,7 @@ class WikiPage < ActiveRecord::Base :url => Proc.new {|o| {:controller => 'wiki', :action => 'show', :project_id => o.wiki.project, :id => o.title}} acts_as_searchable :columns => ['title', "#{WikiContent.table_name}.text"], - :include => [{:wiki => :project}, :content], + :scope => preload(:wiki => :project).joins(:content, {:wiki => :project}), :permission => :view_wiki_pages, :project_key => "#{Wiki.table_name}.project_id" @@ -43,6 +43,7 @@ class WikiPage < ActiveRecord::Base validates_format_of :title, :with => /\A[^,\.\/\?\;\|\s]*\z/ validates_uniqueness_of :title, :scope => :wiki_id, :case_sensitive => false validates_associated :content + attr_protected :id validate :validate_parent_title before_destroy :remove_redirects @@ -180,12 +181,10 @@ class WikiPage < ActiveRecord::Base def save_with_content(content) ret = nil transaction do - self.content = content - if new_record? - # Rails automatically saves associated content - ret = save - else - ret = save && (content.text_changed? ? content.save : true) + ret = save + if content.text_changed? + self.content = content + ret = ret && content.changed? end raise ActiveRecord::Rollback unless ret end diff --git a/app/models/wiki_redirect.rb b/app/models/wiki_redirect.rb index 403fb5c52..166453138 100644 --- a/app/models/wiki_redirect.rb +++ b/app/models/wiki_redirect.rb @@ -20,4 +20,5 @@ class WikiRedirect < ActiveRecord::Base validates_presence_of :title, :redirects_to validates_length_of :title, :redirects_to, :maximum => 255 + attr_protected :id end diff --git a/app/models/workflow_rule.rb b/app/models/workflow_rule.rb index 829b88a32..3d1b75bd0 100644 --- a/app/models/workflow_rule.rb +++ b/app/models/workflow_rule.rb @@ -24,6 +24,7 @@ class WorkflowRule < ActiveRecord::Base belongs_to :new_status, :class_name => 'IssueStatus', :foreign_key => 'new_status_id' validates_presence_of :role, :tracker, :old_status + attr_protected :id # Copies workflows from source to targets def self.copy(source_tracker, source_role, target_trackers, target_roles) @@ -34,7 +35,7 @@ class WorkflowRule < ActiveRecord::Base target_trackers = [target_trackers].flatten.compact target_roles = [target_roles].flatten.compact - target_trackers = Tracker.sorted.all if target_trackers.empty? + target_trackers = Tracker.sorted.to_a if target_trackers.empty? target_roles = Role.all if target_roles.empty? target_trackers.each do |target_tracker| diff --git a/app/models/workflow_transition.rb b/app/models/workflow_transition.rb index 6b04d5983..e88769aa7 100644 --- a/app/models/workflow_transition.rb +++ b/app/models/workflow_transition.rb @@ -40,7 +40,7 @@ class WorkflowTransition < WorkflowRule roles = Array.wrap roles transaction do - records = WorkflowTransition.where(:tracker_id => trackers.map(&:id), :role_id => roles.map(&:id)).all + records = WorkflowTransition.where(:tracker_id => trackers.map(&:id), :role_id => roles.map(&:id)).to_a transitions.each do |old_status_id, transitions_by_new_status| transitions_by_new_status.each do |new_status_id, transition_by_rule| diff --git a/app/views/common/_tabs.html.erb b/app/views/common/_tabs.html.erb index 454b5d772..ffb7f2afa 100644 --- a/app/views/common/_tabs.html.erb +++ b/app/views/common/_tabs.html.erb @@ -8,8 +8,8 @@ <% end -%> </ul> <div class="tabs-buttons" style="display:none;"> - <button class="tab-left" type="button" onclick="moveTabLeft(this);"></button> - <button class="tab-right" type="button" onclick="moveTabRight(this);"></button> + <button class="tab-left" onclick="moveTabLeft(this); return false;"></button> + <button class="tab-right" onclick="moveTabRight(this); return false;"></button> </div> </div> diff --git a/app/views/groups/_memberships.html.erb b/app/views/groups/_memberships.html.erb index 777a0df7c..ec275c594 100644 --- a/app/views/groups/_memberships.html.erb +++ b/app/views/groups/_memberships.html.erb @@ -1,5 +1,5 @@ <% roles = Role.find_all_givable %> -<% projects = Project.active.all %> +<% projects = Project.active.to_a %> <div class="splitcontentleft"> <% if @group.memberships.any? %> diff --git a/app/views/projects/settings/_members.html.erb b/app/views/projects/settings/_members.html.erb index ba7bf91f1..392d1d4b5 100644 --- a/app/views/projects/settings/_members.html.erb +++ b/app/views/projects/settings/_members.html.erb @@ -1,6 +1,6 @@ <%= error_messages_for 'member' %> <% roles = Role.find_all_givable - members = @project.member_principals.includes(:member_roles, :roles, :principal).all.sort %> + members = @project.member_principals.includes(:member_roles, :roles, :principal).to_a.sort %> <div class="splitcontentleft"> <% if members.any? %> diff --git a/app/views/timelog/_form.html.erb b/app/views/timelog/_form.html.erb index b51f98dad..955c2d06b 100644 --- a/app/views/timelog/_form.html.erb +++ b/app/views/timelog/_form.html.erb @@ -8,7 +8,7 @@ <% elsif params[:issue_id] %> <%= hidden_field_tag 'issue_id', params[:issue_id] %> <% else %> - <p><%= f.select :project_id, project_tree_options_for_select(Project.allowed_to(:log_time).all, :selected => @time_entry.project, :include_blank => true) %></p> + <p><%= f.select :project_id, project_tree_options_for_select(Project.allowed_to(:log_time).to_a, :selected => @time_entry.project, :include_blank => true) %></p> <% end %> <% end %> <p> diff --git a/app/views/users/_memberships.html.erb b/app/views/users/_memberships.html.erb index c0d8051ae..cd4201727 100644 --- a/app/views/users/_memberships.html.erb +++ b/app/views/users/_memberships.html.erb @@ -1,5 +1,5 @@ <% roles = Role.find_all_givable %> -<% projects = Project.active.all %> +<% projects = Project.active.to_a %> <div class="splitcontentleft"> <% if @user.memberships.any? %> diff --git a/app/views/wiki/edit.html.erb b/app/views/wiki/edit.html.erb index 3a5a4709f..40e6b792a 100644 --- a/app/views/wiki/edit.html.erb +++ b/app/views/wiki/edit.html.erb @@ -23,7 +23,7 @@ <%= fp.select :parent_id, content_tag('option', '', :value => '') + wiki_page_options_for_select( - @wiki.pages.includes(:parent).all - + @wiki.pages.includes(:parent).to_a - @page.self_and_descendants, @page.parent) %> </p> <% end %> diff --git a/app/views/wiki/rename.html.erb b/app/views/wiki/rename.html.erb index c1a8f33ac..85319520d 100644 --- a/app/views/wiki/rename.html.erb +++ b/app/views/wiki/rename.html.erb @@ -13,7 +13,7 @@ <p><%= f.select :parent_id, content_tag('option', '', :value => '') + wiki_page_options_for_select( - @wiki.pages.includes(:parent).all - @page.self_and_descendants, + @wiki.pages.includes(:parent).to_a - @page.self_and_descendants, @page.parent), :label => :field_parent_title %></p> </div> diff --git a/bin/about b/bin/about new file mode 100755 index 000000000..cfec3b406 --- /dev/null +++ b/bin/about @@ -0,0 +1,6 @@ +#!/usr/bin/env ruby + +ENV["RAILS_ENV"] ||= "production" +require File.expand_path(File.dirname(__FILE__) + "/../config/environment") +puts +puts Redmine::Info.environment diff --git a/bin/bundle b/bin/bundle new file mode 100644 index 000000000..e3c2f622b --- /dev/null +++ b/bin/bundle @@ -0,0 +1,3 @@ +#!/usr/bin/env ruby.exe +ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) +load Gem.bin_path('bundler', 'bundle') diff --git a/bin/rails b/bin/rails new file mode 100644 index 000000000..b9f87878f --- /dev/null +++ b/bin/rails @@ -0,0 +1,4 @@ +#!/usr/bin/env ruby.exe +APP_PATH = File.expand_path('../../config/application', __FILE__) +require_relative '../config/boot' +require 'rails/commands' diff --git a/bin/rake b/bin/rake new file mode 100644 index 000000000..f6ed5a2a6 --- /dev/null +++ b/bin/rake @@ -0,0 +1,4 @@ +#!/usr/bin/env ruby.exe +require_relative '../config/boot' +require 'rake' +Rake.application.run diff --git a/config/application.rb b/config/application.rb index 58d949a48..b05c5287e 100644 --- a/config/application.rb +++ b/config/application.rb @@ -2,12 +2,7 @@ require File.expand_path('../boot', __FILE__) require 'rails/all' -if defined?(Bundler) - # If you precompile assets before deploying to production, use this line - Bundler.require(*Rails.groups(:assets => %w(development test))) - # If you want your assets lazily compiled in production, use this line - # Bundler.require(:default, :assets, Rails.env) -end +Bundler.require(*Rails.groups) module RedmineApp class Application < Rails::Application @@ -33,7 +28,7 @@ module RedmineApp # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] # config.i18n.default_locale = :de - I18n.enforce_available_locales = false + I18n.enforce_available_locales = true # Configure the default encoding used in templates for Ruby 1.9. config.encoding = "utf-8" diff --git a/config/boot.rb b/config/boot.rb index 4489e5868..359673666 100644 --- a/config/boot.rb +++ b/config/boot.rb @@ -1,5 +1,3 @@ -require 'rubygems' - # Set up gems listed in the Gemfile. ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) diff --git a/config/database.yml.example b/config/database.yml.example index 5bcf17bd6..57bc51605 100644 --- a/config/database.yml.example +++ b/config/database.yml.example @@ -1,5 +1,4 @@ -# Default setup is given for MySQL with ruby1.9. If you're running Redmine -# with MySQL and ruby1.8, replace the adapter name with `mysql`. +# Default setup is given for MySQL with ruby1.9. # Examples for PostgreSQL, SQLite3 and SQL Server can be found at the end. # Line indentation must be 2 spaces (no tabs). diff --git a/config/environment.rb b/config/environment.rb index 1d9a39669..705e4ecd7 100644 --- a/config/environment.rb +++ b/config/environment.rb @@ -1,4 +1,4 @@ -# Load the rails application +# Load the Rails application require File.expand_path('../application', __FILE__) # Make sure there's no plugin in vendor/plugin before starting @@ -10,5 +10,5 @@ if Dir.glob(File.join(vendor_plugins_dir, "*")).any? exit 1 end -# Initialize the rails application -RedmineApp::Application.initialize! +# Initialize the Rails application +Rails.application.initialize! diff --git a/config/environments/development.rb b/config/environments/development.rb index bd66a784e..f7b15e140 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -1,19 +1,21 @@ -# Settings specified here will take precedence over those in config/application.rb -RedmineApp::Application.configure do +Rails.application.configure do + # Settings specified here will take precedence over those in config/application.rb + # In the development environment your application's code is reloaded on # every request. This slows down response time but is perfect for development # since you don't have to restart the webserver when you make code changes. - config.cache_classes = false + config.cache_classes = false - # Log error messages when you accidentally call methods on nil. - config.whiny_nils = true + # Do not eager load code on boot. + config.eager_load = false # Show full error reports and disable caching - #config.action_controller.consider_all_requests_local = true - config.action_controller.perform_caching = false + config.consider_all_requests_local = true + config.action_controller.perform_caching = false - # Don't care if the mailer can't send + # Disable delivery errors config.action_mailer.raise_delivery_errors = false + # Print deprecation notices to stderr and the Rails logger. config.active_support.deprecation = [:stderr, :log] end diff --git a/config/environments/production.rb b/config/environments/production.rb index ecb4cf902..85cd3890c 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -1,33 +1,25 @@ -# Settings specified here will take precedence over those in config/application.rb -RedmineApp::Application.configure do - # The production environment is meant for finished, "live" apps. - # Code is not reloaded between requests +Rails.application.configure do + # Settings specified here will take precedence over those in config/application.rb + + # Code is not reloaded between requests. config.cache_classes = true - ##### - # Customize the default logger - # http://www.ruby-doc.org/stdlib-1.8.7/libdoc/logger/rdoc/Logger.html - # - # Use a different logger for distributed setups - # config.logger = SyslogLogger.new - # - # Rotate logs bigger than 1MB, keeps no more than 7 rotated logs around. - # When setting a new Logger, make sure to set it's log level too. - # - # config.logger = Logger.new(config.log_path, 7, 1048576) - # config.logger.level = Logger::INFO + # Eager load code on boot. This eager loads most of Rails and + # your application in memory, allowing both threaded web servers + # and those relying on copy on write to perform better. + # Rake tasks automatically ignore this option for performance. + config.eager_load = true - # Full error reports are disabled and caching is turned on + # Full error reports are disabled and caching is turned on. + config.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 if you bad email addresses should just be ignored + # Disable delivery errors config.action_mailer.raise_delivery_errors = false # No email in production log config.action_mailer.logger = nil + # Print deprecation notices to the Rails logger. config.active_support.deprecation = :log end diff --git a/config/environments/test.rb b/config/environments/test.rb index f3d0ee9b8..249910443 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -1,16 +1,19 @@ -# Settings specified here will take precedence over those in config/application.rb -RedmineApp::Application.configure do +Rails.application.configure do + # Settings specified here will take precedence over those in config/application.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 + # Do not eager load code on boot. This avoids loading your whole application + # just for the purpose of running a single test. If you are using a tool that + # preloads Rails for running tests, you may have to set it to true. + config.eager_load = false # Show full error reports and disable caching - #config.action_controller.consider_all_requests_local = true + config.consider_all_requests_local = true config.action_controller.perform_caching = false config.action_mailer.perform_deliveries = true @@ -20,10 +23,10 @@ RedmineApp::Application.configure do # ActionMailer::Base.deliveries array. config.action_mailer.delivery_method = :test - # Skip protect_from_forgery in requests - # http://m.onkey.org/2007/9/28/csrf-protection-for-your-existing-rails-application + # Disable request forgery protection in test environment. config.action_controller.allow_forgery_protection = false + # Print deprecation notices to stderr and the Rails logger. config.active_support.deprecation = [:stderr, :log] config.secret_token = 'a secret token for running the tests' diff --git a/config/environments/test_pgsql.rb b/config/environments/test_pgsql.rb index 45cb09bdd..258914d20 100644 --- a/config/environments/test_pgsql.rb +++ b/config/environments/test_pgsql.rb @@ -1 +1,2 @@ +# Same as test.rb instance_eval File.read(File.join(File.dirname(__FILE__), 'test.rb')) diff --git a/config/environments/test_sqlite3.rb b/config/environments/test_sqlite3.rb index 45cb09bdd..258914d20 100644 --- a/config/environments/test_sqlite3.rb +++ b/config/environments/test_sqlite3.rb @@ -1 +1,2 @@ +# Same as test.rb instance_eval File.read(File.join(File.dirname(__FILE__), 'test.rb')) diff --git a/config/initializers/10-patches.rb b/config/initializers/10-patches.rb index 8df4cdec5..ff74c308c 100644 --- a/config/initializers/10-patches.rb +++ b/config/initializers/10-patches.rb @@ -54,56 +54,23 @@ module ActionView end end -# Do not HTML escape text templates -module ActionView - class Template - module Handlers - class ERB - def call(template) - if template.source.encoding_aware? - # First, convert to BINARY, so in case the encoding is - # wrong, we can still find an encoding tag - # (<%# encoding %>) inside the String using a regular - # expression - template_source = template.source.dup.force_encoding("BINARY") - - erb = template_source.gsub(ENCODING_TAG, '') - encoding = $2 - - erb.force_encoding valid_encoding(template.source.dup, encoding) - - # Always make sure we return a String in the default_internal - erb.encode! - else - erb = template.source.dup - end - - self.class.erb_implementation.new( - erb, - :trim => (self.class.erb_trim_mode == "-"), - :escape => template.identifier =~ /\.text/ # only escape HTML templates - ).src - end - end - end - end -end - ActionView::Base.field_error_proc = Proc.new{ |html_tag, instance| html_tag || ''.html_safe } # HTML5: <option value=""></option> is invalid, use <option value=""> </option> instead module ActionView module Helpers - class InstanceTag - private - def add_options_with_non_empty_blank_option(option_tags, options, value = nil) - if options[:include_blank] == true - options = options.dup - options[:include_blank] = ' '.html_safe + module Tags + class Base + private + def add_options_with_non_empty_blank_option(option_tags, options, value = nil) + if options[:include_blank] == true + options = options.dup + options[:include_blank] = ' '.html_safe + end + add_options_without_non_empty_blank_option(option_tags, options, value) end - add_options_without_non_empty_blank_option(option_tags, options, value) + alias_method_chain :add_options, :non_empty_blank_option end - alias_method_chain :add_options, :non_empty_blank_option end module FormTagHelper diff --git a/config/initializers/30-redmine.rb b/config/initializers/30-redmine.rb index f0fc4d4c6..a736902c9 100644 --- a/config/initializers/30-redmine.rb +++ b/config/initializers/30-redmine.rb @@ -1,5 +1,7 @@ I18n.default_locale = 'en' I18n.backend = Redmine::I18n::Backend.new +# Forces I18n to load available locales from the backend +I18n.config.available_locales = nil require 'redmine' @@ -20,9 +22,3 @@ Redmine::Plugin.load unless Redmine::Configuration['mirror_plugins_assets_on_startup'] == false Redmine::Plugin.mirror_assets end - -Rails.application.config.to_prepare do - Redmine::FieldFormat::RecordList.subclasses.each do |klass| - klass.instance.reset_target_class - end -end
\ No newline at end of file diff --git a/config/locales/ja.yml b/config/locales/ja.yml index 5d9c3f843..05ba0d6ff 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -249,8 +249,8 @@ ja: field_is_for_all: 全プロジェクト向け field_possible_values: 選択肢 field_regexp: 正規表現 - field_min_length: 最短長 - field_max_length: 最大長 + field_min_length: 最小値 + field_max_length: 最大値 field_value: 値 field_category: カテゴリ field_title: タイトル @@ -305,7 +305,7 @@ ja: field_activity: 活動 field_spent_on: 日付 field_identifier: 識別子 - field_is_filter: フィルタとして使用 + field_is_filter: フィルタとして使う field_issue_to: 関連するチケット field_delay: 遅延 field_assignable: このロールにチケットを割り当て可能 @@ -314,7 +314,7 @@ ja: field_column_names: 項目 field_time_entries: 時間を記録 field_time_zone: タイムゾーン - field_searchable: 検索対象 + field_searchable: 検索条件に設定可能とする field_default_value: デフォルト値 field_comments_sorting: コメントの表示順 field_parent_title: 親ページ @@ -541,7 +541,7 @@ ja: label_subproject_plural: サブプロジェクト label_subproject_new: 新しいサブプロジェクト label_and_its_subprojects: "%{value} とサブプロジェクト" - label_min_max_length: 最短 - 最大長 + label_min_max_length: 最小値 - 最大値の長さ label_list: リストから選択 label_date: 日付 label_integer: 整数 diff --git a/config/locales/zh-TW.yml b/config/locales/zh-TW.yml index 1a0002a93..d6e02156e 100644 --- a/config/locales/zh-TW.yml +++ b/config/locales/zh-TW.yml @@ -997,7 +997,6 @@ label_only: 僅於 label_drop_down_list: 下拉式清單 label_checkboxes: 核取方塊 - label_radio_buttons: 選項按鈕 label_link_values_to: 連結欄位值至此網址 label_custom_field_select_type: 請選擇連結此自訂欄位的物件類型 label_check_for_updates: 檢查更新 @@ -1196,3 +1195,4 @@ description_date_from: 輸入起始日期 description_date_to: 輸入結束日期 text_repository_identifier_info: '僅允許使用小寫英文字母 (a-z), 阿拉伯數字, 虛線與底線。<br />一旦儲存之後, 代碼便無法再次被更改。' + label_radio_buttons: radio buttons diff --git a/config/preinitializer.rb b/config/preinitializer.rb deleted file mode 100644 index 90f789c6d..000000000 --- a/config/preinitializer.rb +++ /dev/null @@ -1,20 +0,0 @@ -begin - require "rubygems" - require "bundler" -rescue LoadError - $stderr.puts "Redmine requires Bundler. Please install it with `gem install bundler`." - exit 1 -end - -if Gem::Version.new(Bundler::VERSION) < Gem::Version.new("1.0.21") - $stderr.puts "Redmine requires Bundler 1.0.21 (you're using #{Bundler::VERSION}).\nPlease install a newer version with `gem install bundler`." - exit 1 -end - -begin - ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", __FILE__) - Bundler.setup -rescue Bundler::GemNotFound - $stderr.puts "Some gems may need to be installed or updated.\nPlease run `bundle install --without development test`." - exit 1 -end diff --git a/config/routes.rb b/config/routes.rb index bb2c5bb12..a988eb311 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -15,7 +15,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -RedmineApp::Application.routes.draw do +Rails.application.routes.draw do root :to => 'welcome#index', :as => 'home' match 'login', :to => 'account#login', :as => 'signin', :via => [:get, :post] @@ -25,10 +25,10 @@ RedmineApp::Application.routes.draw do match 'account/activate', :to => 'account#activate', :via => :get get 'account/activation_email', :to => 'account#activation_email', :as => 'activation_email' - match '/news/preview', :controller => 'previews', :action => 'news', :as => 'preview_news', :via => [:get, :post, :put] - match '/issues/preview/new/:project_id', :to => 'previews#issue', :as => 'preview_new_issue', :via => [:get, :post, :put] - match '/issues/preview/edit/:id', :to => 'previews#issue', :as => 'preview_edit_issue', :via => [:get, :post, :put] - match '/issues/preview', :to => 'previews#issue', :as => 'preview_issue', :via => [:get, :post, :put] + match '/news/preview', :controller => 'previews', :action => 'news', :as => 'preview_news', :via => [:get, :post, :put, :patch] + match '/issues/preview/new/:project_id', :to => 'previews#issue', :as => 'preview_new_issue', :via => [:get, :post, :put, :patch] + match '/issues/preview/edit/:id', :to => 'previews#issue', :as => 'preview_edit_issue', :via => [:get, :post, :put, :patch] + match '/issues/preview', :to => 'previews#issue', :as => 'preview_issue', :via => [:get, :post, :put, :patch] match 'projects/:id/wiki', :to => 'wikis#edit', :via => :post match 'projects/:id/wiki/destroy', :to => 'wikis#destroy', :via => [:get, :post] @@ -74,7 +74,7 @@ RedmineApp::Application.routes.draw do match 'my/order_blocks', :controller => 'my', :action => 'order_blocks', :via => :post resources :users - match 'users/:id/memberships/:membership_id', :to => 'users#edit_membership', :via => :put, :as => 'user_membership' + match 'users/:id/memberships/:membership_id', :to => 'users#edit_membership', :via => [:put, :patch], :as => 'user_membership' match 'users/:id/memberships/:membership_id', :to => 'users#destroy_membership', :via => :delete match 'users/:id/memberships', :to => 'users#edit_membership', :via => :post, :as => 'user_memberships' @@ -113,7 +113,7 @@ RedmineApp::Application.routes.draw do get 'issues/:copy_from/copy', :to => 'issues#new', :as => 'copy_issue' resources :issues, :only => [:index, :new, :create] # issue form update - match 'issues/update_form', :controller => 'issues', :action => 'update_form', :via => [:put, :post], :as => 'issue_form' + match 'issues/update_form', :controller => 'issues', :action => 'update_form', :via => [:put, :patch, :post], :as => 'issue_form' resources :files, :only => [:index, :new, :create] @@ -151,7 +151,7 @@ RedmineApp::Application.routes.draw do post 'rename' get 'history' get 'diff' - match 'preview', :via => [:post, :put] + match 'preview', :via => [:post, :put, :patch] post 'protect' post 'add_attachment' end diff --git a/db/migrate/001_setup.rb b/db/migrate/001_setup.rb index f1b9c1ed4..3cea13591 100644 --- a/db/migrate/001_setup.rb +++ b/db/migrate/001_setup.rb @@ -17,7 +17,10 @@ class Setup < ActiveRecord::Migration - class User < ActiveRecord::Base; end + class User < ActiveRecord::Base + attr_protected :id + end + # model removed class Permission < ActiveRecord::Base; end diff --git a/db/migrate/072_add_enumerations_position.rb b/db/migrate/072_add_enumerations_position.rb index 98092e5cf..cf5646cf9 100644 --- a/db/migrate/072_add_enumerations_position.rb +++ b/db/migrate/072_add_enumerations_position.rb @@ -4,7 +4,7 @@ class AddEnumerationsPosition < ActiveRecord::Migration Enumeration.all.group_by(&:opt).each do |opt, enums| enums.each_with_index do |enum, i| # do not call model callbacks - Enumeration.update_all "position = #{i+1}", {:id => enum.id} + Enumeration.where({:id => enum.id}).update_all("position = #{i+1}") end end end diff --git a/db/migrate/078_add_custom_fields_position.rb b/db/migrate/078_add_custom_fields_position.rb index cb29098fd..ef940eb02 100644 --- a/db/migrate/078_add_custom_fields_position.rb +++ b/db/migrate/078_add_custom_fields_position.rb @@ -4,7 +4,7 @@ class AddCustomFieldsPosition < ActiveRecord::Migration CustomField.all.group_by(&:type).each do |t, fields| fields.each_with_index do |field, i| # do not call model callbacks - CustomField.update_all "position = #{i+1}", {:id => field.id} + CustomField.where({:id => field.id}).update_all("position = #{i+1}") end end end diff --git a/db/migrate/101_populate_changesets_user_id.rb b/db/migrate/101_populate_changesets_user_id.rb index dd493d17d..566363f7c 100644 --- a/db/migrate/101_populate_changesets_user_id.rb +++ b/db/migrate/101_populate_changesets_user_id.rb @@ -7,7 +7,7 @@ class PopulateChangesetsUserId < ActiveRecord::Migration username, email = $1.strip, $3 u = User.find_by_login(username) u ||= User.find_by_mail(email) unless email.blank? - Changeset.update_all("user_id = #{u.id}", ["committer = ?", committer]) unless u.nil? + Changeset.where(["committer = ?", committer]).update_all("user_id = #{u.id}") unless u.nil? end end end diff --git a/db/migrate/20091225164732_remove_enumerations_opt.rb b/db/migrate/20091225164732_remove_enumerations_opt.rb index 72c39e05b..2a445dd3a 100644 --- a/db/migrate/20091225164732_remove_enumerations_opt.rb +++ b/db/migrate/20091225164732_remove_enumerations_opt.rb @@ -5,8 +5,8 @@ class RemoveEnumerationsOpt < ActiveRecord::Migration def self.down add_column :enumerations, :opt, :string, :limit => 4, :default => '', :null => false - Enumeration.update_all("opt = 'IPRI'", "type = 'IssuePriority'") - Enumeration.update_all("opt = 'DCAT'", "type = 'DocumentCategory'") - Enumeration.update_all("opt = 'ACTI'", "type = 'TimeEntryActivity'") + Enumeration.where("type = 'IssuePriority'").update_all("opt = 'IPRI'") + Enumeration.where("type = 'DocumentCategory'").update_all("opt = 'DCAT'") + Enumeration.where("type = 'TimeEntryActivity'").update_all("opt = 'ACTI'") end end diff --git a/db/migrate/20100819172912_enable_calendar_and_gantt_modules_where_appropriate.rb b/db/migrate/20100819172912_enable_calendar_and_gantt_modules_where_appropriate.rb index 59cd40049..5bee50e3a 100644 --- a/db/migrate/20100819172912_enable_calendar_and_gantt_modules_where_appropriate.rb +++ b/db/migrate/20100819172912_enable_calendar_and_gantt_modules_where_appropriate.rb @@ -1,6 +1,6 @@ class EnableCalendarAndGanttModulesWhereAppropriate < ActiveRecord::Migration def self.up - EnabledModule.where(:name => 'issue_tracking').all.each do |e| + EnabledModule.where(:name => 'issue_tracking').each do |e| EnabledModule.create(:name => 'calendar', :project_id => e.project_id) EnabledModule.create(:name => 'gantt', :project_id => e.project_id) end diff --git a/db/migrate/20130215111141_populate_issues_closed_on.rb b/db/migrate/20130215111141_populate_issues_closed_on.rb index b2a828be4..19313d4c8 100644 --- a/db/migrate/20130215111141_populate_issues_closed_on.rb +++ b/db/migrate/20130215111141_populate_issues_closed_on.rb @@ -15,7 +15,8 @@ class PopulateIssuesClosedOn < ActiveRecord::Migration # Then set closed_on for closed issues that weren't up updated by the above UPDATE # No journal was found so we assume that they were closed on creation - Issue.update_all "closed_on = created_on", {:status_id => closed_status_ids, :closed_on => nil} + Issue.where({:status_id => closed_status_ids, :closed_on => nil}). + update_all("closed_on = created_on") end end diff --git a/doc/CHANGELOG b/doc/CHANGELOG index 01f598b8c..c55868d09 100644 --- a/doc/CHANGELOG +++ b/doc/CHANGELOG @@ -86,7 +86,7 @@ http://www.redmine.org/ * Defect #16655: start_date not set despite settings[default_issue_start_date_to_creation_date] being set. * Defect #16668: Redmine links broken when object name contains special characters * Defect #16669: Markdown formatter should use the :no_intra_emphasis extension -* Defect #16708: Form is submitted when switching tab +* Defect #16708: Form is submitted when swithing tab * Defect #16739: custom_fields.json only returns single tracker instead of array of trackers * Defect #16747: Remove useless settings when editing a query from the gantt * Defect #16755: Field set as read-only still available in the issues list context menu diff --git a/doc/INSTALL b/doc/INSTALL index 21ae70c2f..68fd230e2 100644 --- a/doc/INSTALL +++ b/doc/INSTALL @@ -7,7 +7,7 @@ http://www.redmine.org/ == Requirements -* Ruby 1.8.7, 1.9.2, 1.9.3, 2.0 or 2.1 +* Ruby >= 1.9.3 * RubyGems * Bundler >= 1.0.21 @@ -30,9 +30,6 @@ Optional: 3. Configure the database parameters in config/database.yml for the "production" environment (default database is MySQL and ruby1.9) - If you're running Redmine with MySQL and ruby1.8, replace the adapter name - with `mysql` - 4. Install the required gems by running: bundle install --without development test diff --git a/lib/plugins/acts_as_activity_provider/lib/acts_as_activity_provider.rb b/lib/plugins/acts_as_activity_provider/lib/acts_as_activity_provider.rb index fd5e2a6a6..8e29700a7 100644 --- a/lib/plugins/acts_as_activity_provider/lib/acts_as_activity_provider.rb +++ b/lib/plugins/acts_as_activity_provider/lib/acts_as_activity_provider.rb @@ -29,7 +29,7 @@ module Redmine send :include, Redmine::Acts::ActivityProvider::InstanceMethods end - options.assert_valid_keys(:type, :permission, :timestamp, :author_key, :find_options) + options.assert_valid_keys(:type, :permission, :timestamp, :author_key, :find_options, :scope) self.activity_provider_options ||= {} # One model can provide different event types @@ -54,7 +54,7 @@ module Redmine provider_options = activity_provider_options[event_type] raise "#{self.name} can not provide #{event_type} events." if provider_options.nil? - scope = self + scope = (provider_options[:scope] || self) if from && to scope = scope.where("#{provider_options[:timestamp]} BETWEEN ? AND ?", from, to) @@ -79,7 +79,7 @@ module Redmine scope = scope.where(Project.allowed_to_condition(user, "view_#{self.name.underscore.pluralize}".to_sym, options)) end - scope.all(provider_options[:find_options].dup) + scope.to_a end end end diff --git a/lib/plugins/acts_as_attachable/lib/acts_as_attachable.rb b/lib/plugins/acts_as_attachable/lib/acts_as_attachable.rb index a816490cc..e65c68c6f 100644 --- a/lib/plugins/acts_as_attachable/lib/acts_as_attachable.rb +++ b/lib/plugins/acts_as_attachable/lib/acts_as_attachable.rb @@ -29,9 +29,8 @@ module Redmine attachable_options[:view_permission] = options.delete(:view_permission) || "view_#{self.name.pluralize.underscore}".to_sym attachable_options[:delete_permission] = options.delete(:delete_permission) || "edit_#{self.name.pluralize.underscore}".to_sym - has_many :attachments, options.merge(:as => :container, - :order => "#{Attachment.table_name}.created_on ASC, #{Attachment.table_name}.id ASC", - :dependent => :destroy) + has_many :attachments, lambda {order("#{Attachment.table_name}.created_on ASC, #{Attachment.table_name}.id ASC")}, + options.merge(:as => :container, :dependent => :destroy) send :include, Redmine::Acts::Attachable::InstanceMethods before_save :attach_saved_attachments end diff --git a/lib/plugins/acts_as_customizable/lib/acts_as_customizable.rb b/lib/plugins/acts_as_customizable/lib/acts_as_customizable.rb index 928e98872..f4a8b2b51 100644 --- a/lib/plugins/acts_as_customizable/lib/acts_as_customizable.rb +++ b/lib/plugins/acts_as_customizable/lib/acts_as_customizable.rb @@ -27,9 +27,8 @@ module Redmine return if self.included_modules.include?(Redmine::Acts::Customizable::InstanceMethods) cattr_accessor :customizable_options self.customizable_options = options - has_many :custom_values, :as => :customized, - :include => :custom_field, - :order => "#{CustomField.table_name}.position", + has_many :custom_values, lambda {includes(:custom_field).order("#{CustomField.table_name}.position")}, + :as => :customized, :dependent => :delete_all, :validate => false @@ -46,7 +45,7 @@ module Redmine end def available_custom_fields - CustomField.where("type = '#{self.class.name}CustomField'").sorted.all + CustomField.where("type = '#{self.class.name}CustomField'").sorted.to_a end # Sets the values of the object's custom fields diff --git a/lib/plugins/acts_as_searchable/lib/acts_as_searchable.rb b/lib/plugins/acts_as_searchable/lib/acts_as_searchable.rb index 0d4b3cc0f..8cd907b49 100644 --- a/lib/plugins/acts_as_searchable/lib/acts_as_searchable.rb +++ b/lib/plugins/acts_as_searchable/lib/acts_as_searchable.rb @@ -31,6 +31,7 @@ module Redmine # * :permission - permission required to search the model (default to :view_"objects") def acts_as_searchable(options = {}) return if self.included_modules.include?(Redmine::Acts::Searchable::InstanceMethods) + options.assert_valid_keys(:columns, :project_key, :date_column, :order_column, :search_custom_fields, :permission, :scope) cattr_accessor :searchable_options self.searchable_options = options @@ -70,7 +71,7 @@ module Redmine # TODO: make user an argument user = User.current tokens = [] << tokens unless tokens.is_a?(Array) - projects = [] << projects unless projects.nil? || projects.is_a?(Array) + projects = [] << projects if projects.is_a?(Project) limit_options = {} limit_options[:limit] = options[:limit] if options[:limit] @@ -100,7 +101,10 @@ module Redmine tokens_conditions = [sql, * (tokens.collect {|w| "%#{w.downcase}%"} * token_clauses.size).sort] - scope = self.scoped + scope = (searchable_options[:scope] || self) + if scope.is_a? Proc + scope = scope.call + end project_conditions = [] if searchable_options.has_key?(:permission) project_conditions << Project.allowed_to_condition(user, searchable_options[:permission] || :view_project) @@ -118,10 +122,11 @@ module Redmine results_count = 0 scope = scope. - includes(searchable_options[:include]). + joins(searchable_options[:include]). order("#{searchable_options[:order_column]} " + (options[:before] ? 'DESC' : 'ASC')). where(project_conditions). - where(tokens_conditions) + where(tokens_conditions). + uniq results_count = scope.count @@ -129,7 +134,7 @@ module Redmine if options[:offset] scope_with_limit = scope_with_limit.where("#{searchable_options[:date_column]} #{options[:before] ? '<' : '>'} ?", options[:offset]) end - results = scope_with_limit.all + results = scope_with_limit.to_a [results, results_count] end diff --git a/lib/plugins/acts_as_tree/lib/active_record/acts/tree.rb b/lib/plugins/acts_as_tree/lib/active_record/acts/tree.rb index 34fa34560..c078e7edb 100644 --- a/lib/plugins/acts_as_tree/lib/active_record/acts/tree.rb +++ b/lib/plugins/acts_as_tree/lib/active_record/acts/tree.rb @@ -44,7 +44,7 @@ module ActiveRecord configuration.update(options) if options.is_a?(Hash) belongs_to :parent, :class_name => name, :foreign_key => configuration[:foreign_key], :counter_cache => configuration[:counter_cache] - has_many :children, :class_name => name, :foreign_key => configuration[:foreign_key], :order => configuration[:order], :dependent => configuration[:dependent] + has_many :children, lambda {order(configuration[:order])}, :class_name => name, :foreign_key => configuration[:foreign_key], :dependent => configuration[:dependent] scope :roots, lambda { where("#{configuration[:foreign_key]} IS NULL"). diff --git a/lib/plugins/acts_as_watchable/lib/acts_as_watchable.rb b/lib/plugins/acts_as_watchable/lib/acts_as_watchable.rb index e31026dcb..19af8e56c 100644 --- a/lib/plugins/acts_as_watchable/lib/acts_as_watchable.rb +++ b/lib/plugins/acts_as_watchable/lib/acts_as_watchable.rb @@ -68,7 +68,7 @@ module Redmine end def notified_watchers - notified = watcher_users.active + notified = watcher_users.active.to_a notified.reject! {|user| user.mail.blank? || user.mail_notification == 'none'} if respond_to?(:visible?) notified.reject! {|user| !visible?(user)} diff --git a/lib/plugins/awesome_nested_set/.autotest b/lib/plugins/awesome_nested_set/.autotest deleted file mode 100644 index 54518a40a..000000000 --- a/lib/plugins/awesome_nested_set/.autotest +++ /dev/null @@ -1,13 +0,0 @@ -Autotest.add_hook :initialize do |at| - at.clear_mappings - - at.add_mapping %r%^lib/(.*)\.rb$% do |_, m| - at.files_matching %r%^test/#{m[1]}_test.rb$% - end - - at.add_mapping(%r%^test/.*\.rb$%) {|filename, _| filename } - - at.add_mapping %r%^test/fixtures/(.*)s.yml% do |_, _| - at.files_matching %r%^test/.*\.rb$% - end -end
\ No newline at end of file diff --git a/lib/plugins/awesome_nested_set/.gitignore b/lib/plugins/awesome_nested_set/.gitignore deleted file mode 100644 index 373690149..000000000 --- a/lib/plugins/awesome_nested_set/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -awesome_nested_set.sqlite3.db -spec/debug.log -rdoc -coverage -pkg -*.gem -Gemfile.lock -gemfiles/Gemfile*.lock
\ No newline at end of file diff --git a/lib/plugins/awesome_nested_set/.travis.yml b/lib/plugins/awesome_nested_set/.travis.yml deleted file mode 100644 index ad9e670a3..000000000 --- a/lib/plugins/awesome_nested_set/.travis.yml +++ /dev/null @@ -1,18 +0,0 @@ -language: ruby -script: bundle exec rspec spec -env: - - DB=sqlite3 - - DB=sqlite3mem - - DB=postgresql - - DB=mysql -rvm: - - 2.0.0 - - 1.9.3 - - rbx - - jruby-19mode - - 1.8.7 - - jruby-18mode -gemfile: - - gemfiles/Gemfile.rails-3.0.rb - - gemfiles/Gemfile.rails-3.1.rb - - gemfiles/Gemfile.rails-3.2.rb diff --git a/lib/plugins/awesome_nested_set/CHANGELOG b/lib/plugins/awesome_nested_set/CHANGELOG deleted file mode 100644 index a805bfb17..000000000 --- a/lib/plugins/awesome_nested_set/CHANGELOG +++ /dev/null @@ -1,57 +0,0 @@ -2.1.6 -* Fixed rebuild! when there is a default_scope with order [Adrian Serafin] -* Testing with stable bundler, ruby 2.0, MySQL and PostgreSQL [Philip Arndt] -* Optimized move_to for large trees [ericsmith66] - -2.1.5 -* Worked around issues where AR#association wasn't present on Rails 3.0.x. [Philip Arndt] -* Adds option 'order_column' which defaults to 'left_column_name'. [gudata] -* Added moving with order functionality. [Sytse Sijbrandij] -* Use tablename in all select queries. [Mikhail Dieterle] -* Made sure all descendants' depths are updated when moving parent, not just immediate child. [Phil Thompson] -* Add documentation of the callbacks. [Tobias Maier] - -2.1.4 -* nested_set_options accept both Class & AR Relation. [Semyon Perepelitsa] -* Reduce the number of queries triggered by the canonical usage of `i.level` in the `nested_set` helpers. [thedarkone] -* Specifically require active_record [Bogdan Gusiev] -* compute_level now checks for a non nil association target. [Joel Nimety] - -2.1.3 -* Update child depth when parent node is moved. [Amanda Wagener] -* Added move_to_child_with_index. [Ben Zhang] -* Optimised self_and_descendants for when there's an index on lft. [Mark Torrance] -* Added support for an unsaved record to return the right 'root'. [Philip Arndt] - -2.1.2 -* Fixed regressions introduced. [Philip Arndt] - -2.1.1 -* Added 'depth' which indicates how many levels deep the node is. - This only works when you have a column called 'depth' in your table, - otherwise it doesn't set itself. [Philip Arndt] -* Rails 3.2 support added. [Gabriel Sobrinho] -* Oracle compatibility added. [Pikender Sharma] -* Adding row locking to deletion, locking source of pivot values, and adding retry on collisions. [Markus J. Q. Roberts] -* Added method and helper for sorting children by column. [bluegod] -* Fixed .all_roots_valid? to work with Postgres. [Joshua Clayton] -* Made compatible with polymorphic belongs_to. [Graham Randall] -* Added in the association callbacks to the children :has_many association. [Michael Deering] -* Modified helper to allow using array of objects as argument. [Rahmat Budiharso] -* Fixed cases where we were calling attr_protected. [Jacob Swanner] -* Fixed nil cases involving lft and rgt. [Stuart Coyle] and [Patrick Morgan] - -2.0.2 -* Fixed deprecation warning under Rails 3.1 [Philip Arndt] -* Converted Test::Unit matchers to RSpec. [Uģis Ozols] -* Added inverse_of to associations to improve performance rendering trees. [Sergio Cambra] -* Added row locking and fixed some race conditions. [Markus J. Q. Roberts] - -2.0.1 -* Fixed a bug with move_to not using nested_set_scope [Andreas Sekine] - -2.0.0.pre -* Expect Rails 3 -* Changed how callbacks work. Returning false in a before_move action does not block save operations. Use a validation or exception in the callback if you need that. -* Switched to RSpec -* Remove use of Comparable diff --git a/lib/plugins/awesome_nested_set/CONTRIBUTING.md b/lib/plugins/awesome_nested_set/CONTRIBUTING.md deleted file mode 100644 index 112b942ef..000000000 --- a/lib/plugins/awesome_nested_set/CONTRIBUTING.md +++ /dev/null @@ -1,14 +0,0 @@ -# Contributing to AwesomeNestedSet - -If you find what you might think is a bug: - -1. Check the [GitHub issue tracker](https://github.com/collectiveidea/awesome_nested_set/issues/) to see if anyone else has had the same issue. -2. If you don't see anything, create an issue with information on how to reproduce it. - -If you want to contribute an enhancement or a fix: - -1. Fork [the project on GitHub](https://github.com/collectiveidea/awesome_nested_set) -2. Make your changes with tests. -3. Commit the changes without making changes to the [Rakefile](Rakefile) or any other files that aren't related to your enhancement or fix. -4. Write an entry in the [CHANGELOG](CHANGELOG) -5. Send a pull request. diff --git a/lib/plugins/awesome_nested_set/Gemfile b/lib/plugins/awesome_nested_set/Gemfile deleted file mode 100644 index ca0c5f95c..000000000 --- a/lib/plugins/awesome_nested_set/Gemfile +++ /dev/null @@ -1,38 +0,0 @@ -gem 'combustion', :github => 'pat/combustion', :branch => 'master' - -source 'https://rubygems.org' - -gemspec :path => File.expand_path('../', __FILE__) - -platforms :jruby do - gem 'activerecord-jdbcsqlite3-adapter' - gem 'activerecord-jdbcmysql-adapter' - gem 'jdbc-mysql' - gem 'activerecord-jdbcpostgresql-adapter' - gem 'jruby-openssl' -end - -platforms :ruby do - gem 'sqlite3' - gem 'mysql2', (MYSQL2_VERSION if defined? MYSQL2_VERSION) - gem 'pg' -end - -RAILS_VERSION = nil unless defined? RAILS_VERSION -gem 'railties', RAILS_VERSION -gem 'activerecord', RAILS_VERSION -gem 'actionpack', RAILS_VERSION - -platforms :rbx do - gem 'rubysl', '~> 2.0' - gem 'rubysl-test-unit' -end - - -# Add Oracle Adapters -# gem 'ruby-oci8' -# gem 'activerecord-oracle_enhanced-adapter' - -# Debuggers -gem 'pry' -gem 'pry-nav' diff --git a/lib/plugins/awesome_nested_set/MIT-LICENSE b/lib/plugins/awesome_nested_set/MIT-LICENSE deleted file mode 100644 index 7cdb82927..000000000 --- a/lib/plugins/awesome_nested_set/MIT-LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -Copyright (c) 2007-2011 Collective Idea - -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/lib/plugins/awesome_nested_set/README.md b/lib/plugins/awesome_nested_set/README.md deleted file mode 100644 index 58bb86ee5..000000000 --- a/lib/plugins/awesome_nested_set/README.md +++ /dev/null @@ -1,163 +0,0 @@ -# AwesomeNestedSet - -Awesome Nested Set is an implementation of the nested set pattern for ActiveRecord models. -It is a replacement for acts_as_nested_set and BetterNestedSet, but more awesome. - -Version 2 supports Rails 3. Gem versions prior to 2.0 support Rails 2. - -## What makes this so awesome? - -This is a new implementation of nested set based off of BetterNestedSet that fixes some bugs, removes tons of duplication, adds a few useful methods, and adds STI support. - -[![Code Climate](https://codeclimate.com/github/collectiveidea/awesome_nested_set.png)](https://codeclimate.com/github/collectiveidea/awesome_nested_set) - -## Installation - -Add to your Gemfile: - -```ruby -gem 'awesome_nested_set' -``` - -## Usage - -To make use of `awesome_nested_set`, your model needs to have 3 fields: -`lft`, `rgt`, and `parent_id`. The names of these fields are configurable. -You can also have an optional field, `depth`: - -```ruby -class CreateCategories < ActiveRecord::Migration - def self.up - create_table :categories do |t| - t.string :name - t.integer :parent_id - t.integer :lft - t.integer :rgt - t.integer :depth # this is optional. - end - end - - def self.down - drop_table :categories - end -end -``` - -Enable the nested set functionality by declaring `acts_as_nested_set` on your model - -```ruby -class Category < ActiveRecord::Base - acts_as_nested_set -end -``` - -Run `rake rdoc` to generate the API docs and see [CollectiveIdea::Acts::NestedSet](lib/awesome_nested_set/awesome_nested_set.rb) for more information. - -## Callbacks - -There are three callbacks called when moving a node: -`before_move`, `after_move` and `around_move`. - -```ruby -class Category < ActiveRecord::Base - acts_as_nested_set - - after_move :rebuild_slug - around_move :da_fancy_things_around - - private - - def rebuild_slug - # do whatever - end - - def da_fancy_things_around - # do something... - yield # actually moves - # do something else... - end -end -``` - -Beside this there are also hooks to act on the newly added or removed children. - -```ruby -class Category < ActiveRecord::Base - acts_as_nested_set :before_add => :do_before_add_stuff, - :after_add => :do_after_add_stuff, - :before_remove => :do_before_remove_stuff, - :after_remove => :do_after_remove_stuff - - private - - def do_before_add_stuff(child_node) - # do whatever with the child - end - - def do_after_add_stuff(child_node) - # do whatever with the child - end - - def do_before_remove_stuff(child_node) - # do whatever with the child - end - - def do_after_remove_stuff(child_node) - # do whatever with the child - end -end -``` - -## Protecting attributes from mass assignment - -It's generally best to "whitelist" the attributes that can be used in mass assignment: - -```ruby -class Category < ActiveRecord::Base - acts_as_nested_set - attr_accessible :name, :parent_id -end -``` - -If for some reason that is not possible, you will probably want to protect the `lft` and `rgt` attributes: - -```ruby -class Category < ActiveRecord::Base - acts_as_nested_set - attr_protected :lft, :rgt -end -``` - -## Conversion from other trees - -Coming from acts_as_tree or another system where you only have a parent_id? No problem. Simply add the lft & rgt fields as above, and then run: - -```ruby -Category.rebuild! -``` - -Your tree will be converted to a valid nested set. Awesome! - -## View Helper - -The view helper is called #nested_set_options. - -Example usage: - -```erb -<%= f.select :parent_id, nested_set_options(Category, @category) {|i| "#{'-' * i.level} #{i.name}" } %> - -<%= select_tag 'parent_id', options_for_select(nested_set_options(Category) {|i| "#{'-' * i.level} #{i.name}" } ) %> -``` - -See [CollectiveIdea::Acts::NestedSet::Helper](lib/awesome_nested_set/helper.rb) for more information about the helpers. - -## References - -You can learn more about nested sets at: http://threebit.net/tutorials/nestedset/tutorial1.html - -## How to contribute - -Please see the ['Contributing' document](CONTRIBUTING.md). - -Copyright © 2008 - 2013 Collective Idea, released under the MIT license diff --git a/lib/plugins/awesome_nested_set/Rakefile b/lib/plugins/awesome_nested_set/Rakefile deleted file mode 100644 index d5c79129a..000000000 --- a/lib/plugins/awesome_nested_set/Rakefile +++ /dev/null @@ -1,32 +0,0 @@ -# -*- encoding: utf-8 -*- -$LOAD_PATH.unshift File.expand_path("../lib", __FILE__) -require 'rubygems' -require 'bundler/setup' -require 'awesome_nested_set/version' - -task :default => :spec - -task :spec do - %w(3.0 3.1 3.2).each do |rails_version| - puts "\n" + (cmd = "BUNDLE_GEMFILE='gemfiles/Gemfile.rails-#{rails_version}.rb' bundle exec rspec spec") - system cmd - end -end - -task :build do - system "gem build awesome_nested_set.gemspec" -end - -task :release => :build do - system "gem push awesome_nested_set-#{ActsAsGeocodable::VERSION}.gem" -end - -require 'rdoc/task' -desc 'Generate documentation for the awesome_nested_set plugin.' -Rake::RDocTask.new(:rdoc) do |rdoc| - rdoc.rdoc_dir = 'rdoc' - rdoc.title = 'AwesomeNestedSet' - rdoc.options << '--line-numbers' << '--inline-source' - rdoc.rdoc_files.include('README.rdoc') - rdoc.rdoc_files.include('lib/**/*.rb') -end diff --git a/lib/plugins/awesome_nested_set/awesome_nested_set.gemspec b/lib/plugins/awesome_nested_set/awesome_nested_set.gemspec deleted file mode 100644 index f4f858efc..000000000 --- a/lib/plugins/awesome_nested_set/awesome_nested_set.gemspec +++ /dev/null @@ -1,24 +0,0 @@ -# -*- encoding: utf-8 -*- -require File.expand_path('../lib/awesome_nested_set/version', __FILE__) - -Gem::Specification.new do |s| - s.name = %q{awesome_nested_set} - s.version = ::AwesomeNestedSet::VERSION - s.authors = ["Brandon Keepers", "Daniel Morrison", "Philip Arndt"] - s.description = %q{An awesome nested set implementation for Active Record} - s.email = %q{info@collectiveidea.com} - s.files = Dir.glob("lib/**/*") + %w(MIT-LICENSE README.md CHANGELOG) - s.homepage = %q{http://github.com/collectiveidea/awesome_nested_set} - s.rdoc_options = ["--inline-source", "--line-numbers"] - s.require_paths = ["lib"] - s.rubygems_version = %q{1.3.6} - s.summary = %q{An awesome nested set implementation for Active Record} - s.license = %q{MIT} - - s.add_runtime_dependency 'activerecord', '>= 3.0.0' - - s.add_development_dependency 'rspec-rails', '~> 2.12' - s.add_development_dependency 'rake', '~> 10' - s.add_development_dependency 'combustion', '>= 0.3.3' - s.add_development_dependency 'database_cleaner' -end diff --git a/lib/plugins/awesome_nested_set/gemfiles/Gemfile.rails-3.0.rb b/lib/plugins/awesome_nested_set/gemfiles/Gemfile.rails-3.0.rb deleted file mode 100644 index 9109812e9..000000000 --- a/lib/plugins/awesome_nested_set/gemfiles/Gemfile.rails-3.0.rb +++ /dev/null @@ -1,4 +0,0 @@ -MYSQL2_VERSION = '~> 0.2.18' -RAILS_VERSION = '~> 3.0.17' - -eval File.read(File.expand_path('../../Gemfile', __FILE__)) diff --git a/lib/plugins/awesome_nested_set/gemfiles/Gemfile.rails-3.1.rb b/lib/plugins/awesome_nested_set/gemfiles/Gemfile.rails-3.1.rb deleted file mode 100644 index fbbb15c8a..000000000 --- a/lib/plugins/awesome_nested_set/gemfiles/Gemfile.rails-3.1.rb +++ /dev/null @@ -1,4 +0,0 @@ -MYSQL2_VERSION = '>= 0.3' -RAILS_VERSION = '~> 3.1.0' - -eval File.read(File.expand_path('../../Gemfile', __FILE__)) diff --git a/lib/plugins/awesome_nested_set/gemfiles/Gemfile.rails-3.2.rb b/lib/plugins/awesome_nested_set/gemfiles/Gemfile.rails-3.2.rb deleted file mode 100644 index 03d117309..000000000 --- a/lib/plugins/awesome_nested_set/gemfiles/Gemfile.rails-3.2.rb +++ /dev/null @@ -1,4 +0,0 @@ -MYSQL2_VERSION = '>= 0.3' -RAILS_VERSION = '~> 3.2.0' - -eval File.read(File.expand_path('../../Gemfile', __FILE__)) diff --git a/lib/plugins/awesome_nested_set/init.rb b/lib/plugins/awesome_nested_set/init.rb deleted file mode 100644 index 8e2cf36ef..000000000 --- a/lib/plugins/awesome_nested_set/init.rb +++ /dev/null @@ -1 +0,0 @@ -require File.dirname(__FILE__) + '/lib/awesome_nested_set' diff --git a/lib/plugins/awesome_nested_set/lib/awesome_nested_set.rb b/lib/plugins/awesome_nested_set/lib/awesome_nested_set.rb deleted file mode 100644 index 37ae5170d..000000000 --- a/lib/plugins/awesome_nested_set/lib/awesome_nested_set.rb +++ /dev/null @@ -1,8 +0,0 @@ -require 'awesome_nested_set/awesome_nested_set' -require 'active_record' -ActiveRecord::Base.send :extend, CollectiveIdea::Acts::NestedSet - -if defined?(ActionView) - require 'awesome_nested_set/helper' - ActionView::Base.send :include, CollectiveIdea::Acts::NestedSet::Helper -end diff --git a/lib/plugins/awesome_nested_set/lib/awesome_nested_set/awesome_nested_set.rb b/lib/plugins/awesome_nested_set/lib/awesome_nested_set/awesome_nested_set.rb deleted file mode 100644 index 603c177d1..000000000 --- a/lib/plugins/awesome_nested_set/lib/awesome_nested_set/awesome_nested_set.rb +++ /dev/null @@ -1,135 +0,0 @@ -require 'awesome_nested_set/columns' -require 'awesome_nested_set/model' - -module CollectiveIdea #:nodoc: - module Acts #:nodoc: - module NestedSet #:nodoc: - - # This acts provides Nested Set functionality. Nested Set is a smart way to implement - # an _ordered_ tree, with the added feature that you can select the children and all of their - # descendants with a single query. The drawback is that insertion or move need some complex - # sql queries. But everything is done here by this module! - # - # Nested sets are appropriate each time you want either an orderd tree (menus, - # commercial categories) or an efficient way of querying big trees (threaded posts). - # - # == API - # - # Methods names are aligned with acts_as_tree as much as possible to make replacment from one - # by another easier. - # - # item.children.create(:name => "child1") - # - - # Configuration options are: - # - # * +:parent_column+ - specifies the column name to use for keeping the position integer (default: parent_id) - # * +:left_column+ - column name for left boundry data, default "lft" - # * +:right_column+ - column name for right boundry data, default "rgt" - # * +:depth_column+ - column name for the depth data, default "depth" - # * +:scope+ - restricts what is to be considered a list. Given a symbol, it'll attach "_id" - # (if it hasn't been already) and use that as the foreign key restriction. You - # can also pass an array to scope by multiple attributes. - # Example: <tt>acts_as_nested_set :scope => [:notable_id, :notable_type]</tt> - # * +:dependent+ - behavior for cascading destroy. If set to :destroy, all the - # child objects are destroyed alongside this object by calling their destroy - # method. If set to :delete_all (default), all the child objects are deleted - # without calling their destroy method. - # * +:counter_cache+ adds a counter cache for the number of children. - # defaults to false. - # Example: <tt>acts_as_nested_set :counter_cache => :children_count</tt> - # * +:order_column+ on which column to do sorting, by default it is the left_column_name - # Example: <tt>acts_as_nested_set :order_column => :position</tt> - # - # See CollectiveIdea::Acts::NestedSet::Model::ClassMethods for a list of class methods and - # CollectiveIdea::Acts::NestedSet::Model for a list of instance methods added - # to acts_as_nested_set models - def acts_as_nested_set(options = {}) - acts_as_nested_set_parse_options! options - - include Model - include Columns - extend Columns - - acts_as_nested_set_relate_parent! - acts_as_nested_set_relate_children! - - attr_accessor :skip_before_destroy - - acts_as_nested_set_prevent_assignment_to_reserved_columns! - acts_as_nested_set_define_callbacks! - end - - private - def acts_as_nested_set_define_callbacks! - # on creation, set automatically lft and rgt to the end of the tree - before_create :set_default_left_and_right - before_save :store_new_parent - after_save :move_to_new_parent, :set_depth! - before_destroy :destroy_descendants - - define_model_callbacks :move - end - - def acts_as_nested_set_relate_children! - has_many_children_options = { - :class_name => self.base_class.to_s, - :foreign_key => parent_column_name, - :order => quoted_order_column_name, - :inverse_of => (:parent unless acts_as_nested_set_options[:polymorphic]), - } - - # Add callbacks, if they were supplied.. otherwise, we don't want them. - [:before_add, :after_add, :before_remove, :after_remove].each do |ar_callback| - has_many_children_options.update(ar_callback => acts_as_nested_set_options[ar_callback]) if acts_as_nested_set_options[ar_callback] - end - - has_many :children, has_many_children_options - end - - def acts_as_nested_set_relate_parent! - belongs_to :parent, :class_name => self.base_class.to_s, - :foreign_key => parent_column_name, - :counter_cache => acts_as_nested_set_options[:counter_cache], - :inverse_of => (:children unless acts_as_nested_set_options[:polymorphic]), - :polymorphic => acts_as_nested_set_options[:polymorphic], - :touch => acts_as_nested_set_options[:touch] - end - - def acts_as_nested_set_default_options - { - :parent_column => 'parent_id', - :left_column => 'lft', - :right_column => 'rgt', - :depth_column => 'depth', - :dependent => :delete_all, # or :destroy - :polymorphic => false, - :counter_cache => false, - :touch => false - }.freeze - end - - def acts_as_nested_set_parse_options!(options) - options = acts_as_nested_set_default_options.merge(options) - - if options[:scope].is_a?(Symbol) && options[:scope].to_s !~ /_id$/ - options[:scope] = "#{options[:scope]}_id".intern - end - - class_attribute :acts_as_nested_set_options - self.acts_as_nested_set_options = options - end - - def acts_as_nested_set_prevent_assignment_to_reserved_columns! - # no assignment to structure fields - [left_column_name, right_column_name, depth_column_name].each do |column| - module_eval <<-"end_eval", __FILE__, __LINE__ - def #{column}=(x) - raise ActiveRecord::ActiveRecordError, "Unauthorized assignment to #{column}: it's an internal field handled by acts_as_nested_set code, use move_to_* methods instead." - end - end_eval - end - end - end - end -end diff --git a/lib/plugins/awesome_nested_set/lib/awesome_nested_set/columns.rb b/lib/plugins/awesome_nested_set/lib/awesome_nested_set/columns.rb deleted file mode 100644 index aba32cb96..000000000 --- a/lib/plugins/awesome_nested_set/lib/awesome_nested_set/columns.rb +++ /dev/null @@ -1,72 +0,0 @@ -# Mixed into both classes and instances to provide easy access to the column names -module CollectiveIdea #:nodoc: - module Acts #:nodoc: - module NestedSet #:nodoc: - module Columns - def left_column_name - acts_as_nested_set_options[:left_column] - end - - def right_column_name - acts_as_nested_set_options[:right_column] - end - - def depth_column_name - acts_as_nested_set_options[:depth_column] - end - - def parent_column_name - acts_as_nested_set_options[:parent_column] - end - - def order_column - acts_as_nested_set_options[:order_column] || left_column_name - end - - def scope_column_names - Array(acts_as_nested_set_options[:scope]) - end - - def quoted_left_column_name - connection.quote_column_name(left_column_name) - end - - def quoted_right_column_name - connection.quote_column_name(right_column_name) - end - - def quoted_depth_column_name - connection.quote_column_name(depth_column_name) - end - - def quoted_parent_column_name - connection.quote_column_name(parent_column_name) - end - - def quoted_scope_column_names - scope_column_names.collect {|column_name| connection.quote_column_name(column_name) } - end - - def quoted_order_column_name - connection.quote_column_name(order_column) - end - - def quoted_order_column_full_name - "#{quoted_table_name}.#{quoted_order_column_name}" - end - - def quoted_left_column_full_name - "#{quoted_table_name}.#{quoted_left_column_name}" - end - - def quoted_right_column_full_name - "#{quoted_table_name}.#{quoted_right_column_name}" - end - - def quoted_parent_column_full_name - "#{quoted_table_name}.#{quoted_parent_column_name}" - end - end - end - end -end diff --git a/lib/plugins/awesome_nested_set/lib/awesome_nested_set/helper.rb b/lib/plugins/awesome_nested_set/lib/awesome_nested_set/helper.rb deleted file mode 100644 index bd8d40df1..000000000 --- a/lib/plugins/awesome_nested_set/lib/awesome_nested_set/helper.rb +++ /dev/null @@ -1,44 +0,0 @@ -# -*- coding: utf-8 -*- -module CollectiveIdea #:nodoc: - module Acts #:nodoc: - module NestedSet #:nodoc: - # This module provides some helpers for the model classes using acts_as_nested_set. - # It is included by default in all views. - # - module Helper - # Returns options for select. - # You can exclude some items from the tree. - # You can pass a block receiving an item and returning the string displayed in the select. - # - # == Params - # * +class_or_item+ - Class name or top level times - # * +mover+ - The item that is being move, used to exlude impossible moves - # * +&block+ - a block that will be used to display: { |item| ... item.name } - # - # == Usage - # - # <%= f.select :parent_id, nested_set_options(Category, @category) {|i| - # "#{'–' * i.level} #{i.name}" - # }) %> - # - def nested_set_options(class_or_item, mover = nil) - if class_or_item.is_a? Array - items = class_or_item.reject { |e| !e.root? } - else - class_or_item = class_or_item.roots if class_or_item.respond_to?(:scoped) - items = Array(class_or_item) - end - result = [] - items.each do |root| - result += root.class.associate_parents(root.self_and_descendants).map do |i| - if mover.nil? || mover.new_record? || mover.move_possible?(i) - [yield(i), i.id] - end - end.compact - end - result - end - end - end - end -end diff --git a/lib/plugins/awesome_nested_set/lib/awesome_nested_set/iterator.rb b/lib/plugins/awesome_nested_set/lib/awesome_nested_set/iterator.rb deleted file mode 100644 index 94aca41ea..000000000 --- a/lib/plugins/awesome_nested_set/lib/awesome_nested_set/iterator.rb +++ /dev/null @@ -1,29 +0,0 @@ -module CollectiveIdea #:nodoc: - module Acts #:nodoc: - module NestedSet #:nodoc: - class Iterator - attr_reader :objects - - def initialize(objects) - @objects = objects - end - - def each_with_level - path = [nil] - objects.each do |o| - if o.parent_id != path.last - # we are on a new level, did we descend or ascend? - if path.include?(o.parent_id) - # remove wrong tailing paths elements - path.pop while path.last != o.parent_id - else - path << o.parent_id - end - end - yield(o, path.length - 1) - end - end - end - end - end -end diff --git a/lib/plugins/awesome_nested_set/lib/awesome_nested_set/model.rb b/lib/plugins/awesome_nested_set/lib/awesome_nested_set/model.rb deleted file mode 100644 index dbbf569a7..000000000 --- a/lib/plugins/awesome_nested_set/lib/awesome_nested_set/model.rb +++ /dev/null @@ -1,204 +0,0 @@ -require 'awesome_nested_set/model/prunable' -require 'awesome_nested_set/model/movable' -require 'awesome_nested_set/model/transactable' -require 'awesome_nested_set/model/relatable' -require 'awesome_nested_set/model/rebuildable' -require 'awesome_nested_set/model/validatable' -require 'awesome_nested_set/iterator' - -module CollectiveIdea #:nodoc: - module Acts #:nodoc: - module NestedSet #:nodoc: - - module Model - extend ActiveSupport::Concern - - included do - delegate :quoted_table_name, :arel_table, :to => self - extend Validatable - extend Rebuildable - include Movable - include Prunable - include Relatable - include Transactable - end - - module ClassMethods - def associate_parents(objects) - return objects unless objects.all? {|o| o.respond_to?(:association)} - - id_indexed = objects.index_by(&:id) - objects.each do |object| - association = object.association(:parent) - parent = id_indexed[object.parent_id] - - if !association.loaded? && parent - association.target = parent - association.set_inverse_instance(parent) - end - end - end - - def children_of(parent_id) - where arel_table[parent_column_name].eq(parent_id) - end - - # Iterates over tree elements and determines the current level in the tree. - # Only accepts default ordering, odering by an other column than lft - # does not work. This method is much more efficent than calling level - # because it doesn't require any additional database queries. - # - # Example: - # Category.each_with_level(Category.root.self_and_descendants) do |o, level| - # - def each_with_level(objects, &block) - Iterator.new(objects).each_with_level(&block) - end - - def leaves - nested_set_scope.where "#{quoted_right_column_full_name} - #{quoted_left_column_full_name} = 1" - end - - def left_of(node) - where arel_table[left_column_name].lt(node) - end - - def left_of_right_side(node) - where arel_table[right_column_name].lteq(node) - end - - def right_of(node) - where arel_table[left_column_name].gteq(node) - end - - def nested_set_scope(options = {}) - options = {:order => quoted_order_column_full_name}.merge(options) - - order(options.delete(:order)).scoped options - end - - def primary_key_scope(id) - where arel_table[primary_key].eq(id) - end - - def root - roots.first - end - - def roots - nested_set_scope.children_of nil - end - end # end class methods - - # Any instance method that returns a collection makes use of Rails 2.1's named_scope (which is bundled for Rails 2.0), so it can be treated as a finder. - # - # category.self_and_descendants.count - # category.ancestors.find(:all, :conditions => "name like '%foo%'") - # Value of the parent column - def parent_id(target = self) - target[parent_column_name] - end - - # Value of the left column - def left(target = self) - target[left_column_name] - end - - # Value of the right column - def right(target = self) - target[right_column_name] - end - - # Returns true if this is a root node. - def root? - parent_id.nil? - end - - # Returns true is this is a child node - def child? - !root? - end - - # Returns true if this is the end of a branch. - def leaf? - persisted? && right.to_i - left.to_i == 1 - end - - # All nested set queries should use this nested_set_scope, which - # performs finds on the base ActiveRecord class, using the :scope - # declared in the acts_as_nested_set declaration. - def nested_set_scope(options = {}) - if (scopes = Array(acts_as_nested_set_options[:scope])).any? - options[:conditions] = scopes.inject({}) do |conditions,attr| - conditions.merge attr => self[attr] - end - end - - self.class.nested_set_scope options - end - - def to_text - self_and_descendants.map do |node| - "#{'*'*(node.level+1)} #{node.id} #{node.to_s} (#{node.parent_id}, #{node.left}, #{node.right})" - end.join("\n") - end - - protected - - def without_self(scope) - return scope if new_record? - scope.where(["#{self.class.quoted_table_name}.#{self.class.primary_key} != ?", self]) - end - - def store_new_parent - @move_to_new_parent_id = send("#{parent_column_name}_changed?") ? parent_id : false - true # force callback to return true - end - - def has_depth_column? - nested_set_scope.column_names.map(&:to_s).include?(depth_column_name.to_s) - end - - def right_most_bound - right_most_node = - self.class.base_class.unscoped. - order("#{quoted_right_column_full_name} desc").limit(1).lock(true).first - right_most_node ? (right_most_node[right_column_name] || 0) : 0 - end - - def set_depth! - return unless has_depth_column? - - in_tenacious_transaction do - reload - nested_set_scope.primary_key_scope(id). - update_all(["#{quoted_depth_column_name} = ?", level]) - end - self[depth_column_name] = self.level - end - - def set_default_left_and_right - # adds the new node to the right of all existing nodes - self[left_column_name] = right_most_bound + 1 - self[right_column_name] = right_most_bound + 2 - end - - # reload left, right, and parent - def reload_nested_set - reload( - :select => "#{quoted_left_column_full_name}, #{quoted_right_column_full_name}, #{quoted_parent_column_full_name}", - :lock => true - ) - end - - def reload_target(target) - if target.is_a? self.class.base_class - target.reload - else - nested_set_scope.find(target) - end - end - end - end - end -end diff --git a/lib/plugins/awesome_nested_set/lib/awesome_nested_set/model/movable.rb b/lib/plugins/awesome_nested_set/lib/awesome_nested_set/model/movable.rb deleted file mode 100644 index 7b94ca22a..000000000 --- a/lib/plugins/awesome_nested_set/lib/awesome_nested_set/model/movable.rb +++ /dev/null @@ -1,137 +0,0 @@ -require 'awesome_nested_set/move' - -module CollectiveIdea #:nodoc: - module Acts #:nodoc: - module NestedSet #:nodoc: - module Model - module Movable - - def move_possible?(target) - self != target && # Can't target self - same_scope?(target) && # can't be in different scopes - # detect impossible move - within_bounds?(target.left, target.left) && - within_bounds?(target.right, target.right) - end - - # Shorthand method for finding the left sibling and moving to the left of it. - def move_left - move_to_left_of left_sibling - end - - # Shorthand method for finding the right sibling and moving to the right of it. - def move_right - move_to_right_of right_sibling - end - - # Move the node to the left of another node - def move_to_left_of(node) - move_to node, :left - end - - # Move the node to the left of another node - def move_to_right_of(node) - move_to node, :right - end - - # Move the node to the child of another node - def move_to_child_of(node) - move_to node, :child - end - - # Move the node to the child of another node with specify index - def move_to_child_with_index(node, index) - if node.children.empty? - move_to_child_of(node) - elsif node.children.count == index - move_to_right_of(node.children.last) - else - move_to_left_of(node.children[index]) - end - end - - # Move the node to root nodes - def move_to_root - move_to_right_of(root) - end - - # Order children in a nested set by an attribute - # Can order by any attribute class that uses the Comparable mixin, for example a string or integer - # Usage example when sorting categories alphabetically: @new_category.move_to_ordered_child_of(@root, "name") - def move_to_ordered_child_of(parent, order_attribute, ascending = true) - self.move_to_root and return unless parent - - left_neighbor = find_left_neighbor(parent, order_attribute, ascending) - self.move_to_child_of(parent) - - return unless parent.children.many? - - if left_neighbor - self.move_to_right_of(left_neighbor) - else # Self is the left most node. - self.move_to_left_of(parent.children[0]) - end - end - - # Find the node immediately to the left of this node. - def find_left_neighbor(parent, order_attribute, ascending) - left = nil - parent.children.each do |n| - if ascending - left = n if n.send(order_attribute) < self.send(order_attribute) - else - left = n if n.send(order_attribute) > self.send(order_attribute) - end - end - left - end - - def move_to(target, position) - prevent_unpersisted_move - - run_callbacks :move do - in_tenacious_transaction do - target = reload_target(target) - self.reload_nested_set - - Move.new(target, position, self).move - end - after_move_to(target, position) - end - end - - protected - - def after_move_to(target, position) - target.reload_nested_set if target - self.set_depth! - self.descendants.each(&:save) - self.reload_nested_set - end - - def move_to_new_parent - if @move_to_new_parent_id.nil? - move_to_root - elsif @move_to_new_parent_id - move_to_child_of(@move_to_new_parent_id) - end - end - - def out_of_bounds?(left_bound, right_bound) - left <= left_bound && right >= right_bound - end - - def prevent_unpersisted_move - if self.new_record? - raise ActiveRecord::ActiveRecordError, "You cannot move a new node" - end - end - - def within_bounds?(left_bound, right_bound) - !out_of_bounds?(left_bound, right_bound) - end - end - end - end - end -end diff --git a/lib/plugins/awesome_nested_set/lib/awesome_nested_set/model/prunable.rb b/lib/plugins/awesome_nested_set/lib/awesome_nested_set/model/prunable.rb deleted file mode 100644 index bb21d055a..000000000 --- a/lib/plugins/awesome_nested_set/lib/awesome_nested_set/model/prunable.rb +++ /dev/null @@ -1,61 +0,0 @@ -module CollectiveIdea #:nodoc: - module Acts #:nodoc: - module NestedSet #:nodoc: - module Model - module Prunable - - # Prunes a branch off of the tree, shifting all of the elements on the right - # back to the left so the counts still work. - def destroy_descendants - return if right.nil? || left.nil? || skip_before_destroy - - in_tenacious_transaction do - reload_nested_set - # select the rows in the model that extend past the deletion point and apply a lock - nested_set_scope.right_of(left).select(id).lock(true) - - destroy_or_delete_descendants - - # update lefts and rights for remaining nodes - update_siblings_for_remaining_nodes - - # Reload is needed because children may have updated their parent (self) during deletion. - reload - - # Don't allow multiple calls to destroy to corrupt the set - self.skip_before_destroy = true - end - end - - def destroy_or_delete_descendants - if acts_as_nested_set_options[:dependent] == :destroy - descendants.each do |model| - model.skip_before_destroy = true - model.destroy - end - else - descendants.delete_all - end - end - - def update_siblings_for_remaining_nodes - update_siblings(:left) - update_siblings(:right) - end - - def update_siblings(direction) - full_column_name = send("quoted_#{direction}_column_full_name") - column_name = send("quoted_#{direction}_column_name") - - nested_set_scope.where(["#{full_column_name} > ?", right]). - update_all(["#{column_name} = (#{column_name} - ?)", diff]) - end - - def diff - right - left + 1 - end - end - end - end - end -end diff --git a/lib/plugins/awesome_nested_set/lib/awesome_nested_set/model/rebuildable.rb b/lib/plugins/awesome_nested_set/lib/awesome_nested_set/model/rebuildable.rb deleted file mode 100644 index 335736d72..000000000 --- a/lib/plugins/awesome_nested_set/lib/awesome_nested_set/model/rebuildable.rb +++ /dev/null @@ -1,43 +0,0 @@ -require 'awesome_nested_set/tree' - -module CollectiveIdea - module Acts - module NestedSet - module Model - module Rebuildable - - - # Rebuilds the left & rights if unset or invalid. - # Also very useful for converting from acts_as_tree. - def rebuild!(validate_nodes = true) - # default_scope with order may break database queries so we do all operation without scope - unscoped do - Tree.new(self, validate_nodes).rebuild! - end - end - - private - def scope_for_rebuild - scope = proc {} - - if acts_as_nested_set_options[:scope] - scope = proc {|node| - scope_column_names.inject("") {|str, column_name| - column_value = node.send(column_name) - cond = column_value.nil? ? "IS NULL" : "= #{connection.quote(column_value)}" - str << "AND #{connection.quote_column_name(column_name)} #{cond} " - } - } - end - scope - end - - def order_for_rebuild - "#{quoted_left_column_full_name}, #{quoted_right_column_full_name}, #{primary_key}" - end - end - - end - end - end -end diff --git a/lib/plugins/awesome_nested_set/lib/awesome_nested_set/model/relatable.rb b/lib/plugins/awesome_nested_set/lib/awesome_nested_set/model/relatable.rb deleted file mode 100644 index 21de61a9d..000000000 --- a/lib/plugins/awesome_nested_set/lib/awesome_nested_set/model/relatable.rb +++ /dev/null @@ -1,121 +0,0 @@ -module CollectiveIdea - module Acts - module NestedSet - module Model - module Relatable - - # Returns an collection of all parents - def ancestors - without_self self_and_ancestors - end - - # Returns the collection of all parents and self - def self_and_ancestors - nested_set_scope. - where(arel_table[left_column_name].lteq(left)). - where(arel_table[right_column_name].gteq(right)) - end - - # Returns the collection of all children of the parent, except self - def siblings - without_self self_and_siblings - end - - # Returns the collection of all children of the parent, including self - def self_and_siblings - nested_set_scope.children_of parent_id - end - - # Returns a set of all of its nested children which do not have children - def leaves - descendants.where( - "#{quoted_right_column_full_name} - #{quoted_left_column_full_name} = 1" - ) - end - - # Returns the level of this object in the tree - # root level is 0 - def level - parent_id.nil? ? 0 : compute_level - end - - # Returns a collection including all of its children and nested children - def descendants - without_self self_and_descendants - end - - # Returns a collection including itself and all of its nested children - def self_and_descendants - # using _left_ for both sides here lets us benefit from an index on that column if one exists - nested_set_scope.right_of(left).left_of(right) - end - - def is_descendant_of?(other) - within_node?(other, self) && same_scope?(other) - end - - def is_or_is_descendant_of?(other) - (other == self || within_node?(other, self)) && same_scope?(other) - end - - def is_ancestor_of?(other) - within_node?(self, other) && same_scope?(other) - end - - def is_or_is_ancestor_of?(other) - (self == other || within_node?(self, other)) && same_scope?(other) - end - - # Check if other model is in the same scope - def same_scope?(other) - Array(acts_as_nested_set_options[:scope]).all? do |attr| - self.send(attr) == other.send(attr) - end - end - - # Find the first sibling to the left - def left_sibling - siblings.left_of(left).last - end - - # Find the first sibling to the right - def right_sibling - siblings.right_of(left).first - end - - def root - return self_and_ancestors.children_of(nil).first if persisted? - - if parent_id && current_parent = nested_set_scope.find(parent_id) - current_parent.root - else - self - end - end - - protected - - def compute_level - node, nesting = determine_depth - - node == self ? ancestors.count : node.level + nesting - end - - def determine_depth(node = self, nesting = 0) - while (association = node.association(:parent)).loaded? && association.target - nesting += 1 - node = node.parent - end if node.respond_to?(:association) - - [node, nesting] - end - - def within_node?(node, within) - node.left < within.left && within.left < node.right - end - - end - end - end - end -end diff --git a/lib/plugins/awesome_nested_set/lib/awesome_nested_set/model/transactable.rb b/lib/plugins/awesome_nested_set/lib/awesome_nested_set/model/transactable.rb deleted file mode 100644 index bef62d369..000000000 --- a/lib/plugins/awesome_nested_set/lib/awesome_nested_set/model/transactable.rb +++ /dev/null @@ -1,27 +0,0 @@ -module CollectiveIdea #:nodoc: - module Acts #:nodoc: - module NestedSet #:nodoc: - module Model - module Transactable - - protected - def in_tenacious_transaction(&block) - retry_count = 0 - begin - transaction(&block) - rescue ActiveRecord::StatementInvalid => error - raise unless connection.open_transactions.zero? - raise unless error.message =~ /Deadlock found when trying to get lock|Lock wait timeout exceeded/ - raise unless retry_count < 10 - retry_count += 1 - logger.info "Deadlock detected on retry #{retry_count}, restarting transaction" - sleep(rand(retry_count)*0.1) # Aloha protocol - retry - end - end - - end - end - end - end -end diff --git a/lib/plugins/awesome_nested_set/lib/awesome_nested_set/model/validatable.rb b/lib/plugins/awesome_nested_set/lib/awesome_nested_set/model/validatable.rb deleted file mode 100644 index 2772dff5c..000000000 --- a/lib/plugins/awesome_nested_set/lib/awesome_nested_set/model/validatable.rb +++ /dev/null @@ -1,69 +0,0 @@ -require 'awesome_nested_set/set_validator' - -module CollectiveIdea - module Acts - module NestedSet - module Model - module Validatable - - def valid? - left_and_rights_valid? && no_duplicates_for_columns? && all_roots_valid? - end - - def left_and_rights_valid? - SetValidator.new(self).valid? - end - - def no_duplicates_for_columns? - [quoted_left_column_full_name, quoted_right_column_full_name].all? do |column| - # No duplicates - select("#{scope_string}#{column}, COUNT(#{column}) as _count"). - group("#{scope_string}#{column}"). - having("COUNT(#{column}) > 1"). - first.nil? - end - end - - # Wrapper for each_root_valid? that can deal with scope. - def all_roots_valid? - if acts_as_nested_set_options[:scope] - all_roots_valid_by_scope?(roots) - else - each_root_valid?(roots) - end - end - - def all_roots_valid_by_scope?(roots_to_validate) - roots_grouped_by_scope(roots_to_validate).all? do |scope, grouped_roots| - each_root_valid?(grouped_roots) - end - end - - def each_root_valid?(roots_to_validate) - left = right = 0 - roots_to_validate.all? do |root| - (root.left > left && root.right > right).tap do - left = root.left - right = root.right - end - end - end - - private - def roots_grouped_by_scope(roots_to_group) - roots_to_group.group_by {|record| - scope_column_names.collect {|col| record.send(col) } - } - end - - def scope_string - Array(acts_as_nested_set_options[:scope]).map do |c| - connection.quote_column_name(c) - end.push(nil).join(", ") - end - - end - end - end - end -end diff --git a/lib/plugins/awesome_nested_set/lib/awesome_nested_set/move.rb b/lib/plugins/awesome_nested_set/lib/awesome_nested_set/move.rb deleted file mode 100644 index c65e05e88..000000000 --- a/lib/plugins/awesome_nested_set/lib/awesome_nested_set/move.rb +++ /dev/null @@ -1,130 +0,0 @@ -module CollectiveIdea #:nodoc: - module Acts #:nodoc: - module NestedSet #:nodoc: - class Move - attr_reader :target, :position, :instance - - def initialize(target, position, instance) - @target = target - @position = position - @instance = instance - end - - def move - prevent_impossible_move - - bound, other_bound = get_boundaries - - # there would be no change - return if bound == right || bound == left - - # we have defined the boundaries of two non-overlapping intervals, - # so sorting puts both the intervals and their boundaries in order - a, b, c, d = [left, right, bound, other_bound].sort - - lock_nodes_between! a, d - - nested_set_scope.where(where_statement(a, d)).update_all( - conditions(a, b, c, d) - ) - end - - private - - delegate :left, :right, :left_column_name, :right_column_name, - :quoted_left_column_name, :quoted_right_column_name, - :quoted_parent_column_name, :parent_column_name, :nested_set_scope, - :to => :instance - - delegate :arel_table, :class, :to => :instance, :prefix => true - delegate :base_class, :to => :instance_class, :prefix => :instance - - def where_statement(left_bound, right_bound) - instance_arel_table[left_column_name].in(left_bound..right_bound). - or(instance_arel_table[right_column_name].in(left_bound..right_bound)) - end - - def conditions(a, b, c, d) - _conditions = case_condition_for_direction(:quoted_left_column_name) + - case_condition_for_direction(:quoted_right_column_name) + - case_condition_for_parent - - # We want the record to be 'touched' if it timestamps. - if @instance.respond_to?(:updated_at) - _conditions << ", updated_at = :timestamp" - end - - [ - _conditions, - { - :a => a, :b => b, :c => c, :d => d, - :id => instance.id, - :new_parent => new_parent, - :timestamp => Time.now.utc - } - ] - end - - def case_condition_for_direction(column_name) - column = send(column_name) - "#{column} = CASE " + - "WHEN #{column} BETWEEN :a AND :b " + - "THEN #{column} + :d - :b " + - "WHEN #{column} BETWEEN :c AND :d " + - "THEN #{column} + :a - :c " + - "ELSE #{column} END, " - end - - def case_condition_for_parent - "#{quoted_parent_column_name} = CASE " + - "WHEN #{instance_base_class.primary_key} = :id THEN :new_parent " + - "ELSE #{quoted_parent_column_name} END" - end - - def lock_nodes_between!(left_bound, right_bound) - # select the rows in the model between a and d, and apply a lock - instance_base_class.right_of(left_bound).left_of_right_side(right_bound). - select(:id).lock(true) - end - - def root - position == :root - end - - def new_parent - case position - when :child - target.id - else - target[parent_column_name] - end - end - - def get_boundaries - if (bound = target_bound) > right - bound -= 1 - other_bound = right + 1 - else - other_bound = left - 1 - end - [bound, other_bound] - end - - def prevent_impossible_move - if !root && !instance.move_possible?(target) - raise ActiveRecord::ActiveRecordError, "Impossible move, target node cannot be inside moved tree." - end - end - - def target_bound - case position - when :child; right(target) - when :left; left(target) - when :right; right(target) + 1 - else raise ActiveRecord::ActiveRecordError, "Position should be :child, :left, :right or :root ('#{position}' received)." - end - end - end - end - end -end diff --git a/lib/plugins/awesome_nested_set/lib/awesome_nested_set/set_validator.rb b/lib/plugins/awesome_nested_set/lib/awesome_nested_set/set_validator.rb deleted file mode 100644 index 7cb9d3c30..000000000 --- a/lib/plugins/awesome_nested_set/lib/awesome_nested_set/set_validator.rb +++ /dev/null @@ -1,63 +0,0 @@ -module CollectiveIdea #:nodoc: - module Acts #:nodoc: - module NestedSet #:nodoc: - class SetValidator - - def initialize(model) - @model = model - @scope = model.scoped - @parent = arel_table.alias('parent') - end - - def valid? - query.count == 0 - end - - private - - attr_reader :model, :parent - attr_accessor :scope - - delegate :parent_column_name, :primary_key, :left_column_name, :right_column_name, :arel_table, - :quoted_table_name, :quoted_parent_column_full_name, :quoted_left_column_full_name, :quoted_right_column_full_name, :quoted_left_column_name, :quoted_right_column_name, - :to => :model - - def query - join_scope - filter_scope - end - - def join_scope - join_arel = arel_table.join(parent, Arel::Nodes::OuterJoin).on(parent[primary_key].eq(arel_table[parent_column_name])) - self.scope = scope.joins(join_arel.join_sql) - end - - def filter_scope - self.scope = scope.where( - bound_is_null(left_column_name). - or(bound_is_null(right_column_name)). - or(left_bound_greater_than_right). - or(parent_not_null.and(bounds_outside_parent)) - ) - end - - def bound_is_null(column_name) - arel_table[column_name].eq(nil) - end - - def left_bound_greater_than_right - arel_table[left_column_name].gteq(arel_table[right_column_name]) - end - - def parent_not_null - arel_table[parent_column_name].not_eq(nil) - end - - def bounds_outside_parent - arel_table[left_column_name].lteq(parent[left_column_name]).or(arel_table[right_column_name].gteq(parent[right_column_name])) - end - - end - end - end -end diff --git a/lib/plugins/awesome_nested_set/lib/awesome_nested_set/tree.rb b/lib/plugins/awesome_nested_set/lib/awesome_nested_set/tree.rb deleted file mode 100644 index 4a032c2a2..000000000 --- a/lib/plugins/awesome_nested_set/lib/awesome_nested_set/tree.rb +++ /dev/null @@ -1,63 +0,0 @@ -module CollectiveIdea #:nodoc: - module Acts #:nodoc: - module NestedSet #:nodoc: - class Tree - attr_reader :model, :validate_nodes - attr_accessor :indices - - delegate :left_column_name, :right_column_name, :quoted_parent_column_full_name, - :order_for_rebuild, :scope_for_rebuild, - :to => :model - - def initialize(model, validate_nodes) - @model = model - @validate_nodes = validate_nodes - @indices = {} - end - - def rebuild! - # Don't rebuild a valid tree. - return true if model.valid? - - root_nodes.each do |root_node| - # setup index for this scope - indices[scope_for_rebuild.call(root_node)] ||= 0 - set_left_and_rights(root_node) - end - end - - private - - def increment_indice!(node) - indices[scope_for_rebuild.call(node)] += 1 - end - - def set_left_and_rights(node) - set_left!(node) - # find - node_children(node).each { |n| set_left_and_rights(n) } - set_right!(node) - - node.save!(:validate => validate_nodes) - end - - def node_children(node) - model.where(["#{quoted_parent_column_full_name} = ? #{scope_for_rebuild.call(node)}", node]). - order(order_for_rebuild) - end - - def root_nodes - model.where("#{quoted_parent_column_full_name} IS NULL").order(order_for_rebuild) - end - - def set_left!(node) - node[left_column_name] = increment_indice!(node) - end - - def set_right!(node) - node[right_column_name] = increment_indice!(node) - end - end - end - end -end diff --git a/lib/plugins/awesome_nested_set/lib/awesome_nested_set/version.rb b/lib/plugins/awesome_nested_set/lib/awesome_nested_set/version.rb deleted file mode 100644 index c7058f7f4..000000000 --- a/lib/plugins/awesome_nested_set/lib/awesome_nested_set/version.rb +++ /dev/null @@ -1,3 +0,0 @@ -module AwesomeNestedSet - VERSION = '2.1.7' unless defined?(::AwesomeNestedSet::VERSION) -end diff --git a/lib/plugins/awesome_nested_set/spec/awesome_nested_set/helper_spec.rb b/lib/plugins/awesome_nested_set/spec/awesome_nested_set/helper_spec.rb deleted file mode 100644 index 9b2857e04..000000000 --- a/lib/plugins/awesome_nested_set/spec/awesome_nested_set/helper_spec.rb +++ /dev/null @@ -1,102 +0,0 @@ -require 'spec_helper' -require 'awesome_nested_set/helper' - -describe "Helper" do - include CollectiveIdea::Acts::NestedSet::Helper - - before(:all) do - self.class.fixtures :categories - end - - describe "nested_set_options" do - it "test_nested_set_options" do - expected = [ - [" Top Level", 1], - ["- Child 1", 2], - ['- Child 2', 3], - ['-- Child 2.1', 4], - ['- Child 3', 5], - [" Top Level 2", 6] - ] - actual = nested_set_options(Category.scoped) do |c| - "#{'-' * c.level} #{c.name}" - end - actual.should == expected - end - - it "test_nested_set_options_with_mover" do - expected = [ - [" Top Level", 1], - ["- Child 1", 2], - ['- Child 3', 5], - [" Top Level 2", 6] - ] - actual = nested_set_options(Category.scoped, categories(:child_2)) do |c| - "#{'-' * c.level} #{c.name}" - end - actual.should == expected - end - - it "test_nested_set_options_with_class_as_argument" do - expected = [ - [" Top Level", 1], - ["- Child 1", 2], - ['- Child 2', 3], - ['-- Child 2.1', 4], - ['- Child 3', 5], - [" Top Level 2", 6] - ] - actual = nested_set_options(Category) do |c| - "#{'-' * c.level} #{c.name}" - end - actual.should == expected - end - - it "test_nested_set_options_with_class_as_argument_with_mover" do - expected = [ - [" Top Level", 1], - ["- Child 1", 2], - ['- Child 3', 5], - [" Top Level 2", 6] - ] - actual = nested_set_options(Category, categories(:child_2)) do |c| - "#{'-' * c.level} #{c.name}" - end - actual.should == expected - end - - it "test_nested_set_options_with_array_as_argument_without_mover" do - expected = [ - [" Top Level", 1], - ["- Child 1", 2], - ['- Child 2', 3], - ['-- Child 2.1', 4], - ['- Child 3', 5], - [" Top Level 2", 6] - ] - actual = nested_set_options(Category.all) do |c| - "#{'-' * c.level} #{c.name}" - end - actual.length.should == expected.length - expected.flatten.each do |node| - actual.flatten.should include(node) - end - end - - it "test_nested_set_options_with_array_as_argument_with_mover" do - expected = [ - [" Top Level", 1], - ["- Child 1", 2], - ['- Child 3', 5], - [" Top Level 2", 6] - ] - actual = nested_set_options(Category.all, categories(:child_2)) do |c| - "#{'-' * c.level} #{c.name}" - end - actual.length.should == expected.length - expected.flatten.each do |node| - actual.flatten.should include(node) - end - end - end -end diff --git a/lib/plugins/awesome_nested_set/spec/awesome_nested_set_spec.rb b/lib/plugins/awesome_nested_set/spec/awesome_nested_set_spec.rb deleted file mode 100644 index 60cb888b2..000000000 --- a/lib/plugins/awesome_nested_set/spec/awesome_nested_set_spec.rb +++ /dev/null @@ -1,1098 +0,0 @@ -require 'spec_helper' - -describe "AwesomeNestedSet" do - before(:all) do - self.class.fixtures :categories, :departments, :notes, :things, :brokens - end - - describe "defaults" do - it "should have left_column_default" do - Default.acts_as_nested_set_options[:left_column].should == 'lft' - end - - it "should have right_column_default" do - Default.acts_as_nested_set_options[:right_column].should == 'rgt' - end - - it "should have parent_column_default" do - Default.acts_as_nested_set_options[:parent_column].should == 'parent_id' - end - - it "should have scope_default" do - Default.acts_as_nested_set_options[:scope].should be_nil - end - - it "should have left_column_name" do - Default.left_column_name.should == 'lft' - Default.new.left_column_name.should == 'lft' - RenamedColumns.left_column_name.should == 'red' - RenamedColumns.new.left_column_name.should == 'red' - end - - it "should have right_column_name" do - Default.right_column_name.should == 'rgt' - Default.new.right_column_name.should == 'rgt' - RenamedColumns.right_column_name.should == 'black' - RenamedColumns.new.right_column_name.should == 'black' - end - - it "has a depth_column_name" do - Default.depth_column_name.should == 'depth' - Default.new.depth_column_name.should == 'depth' - RenamedColumns.depth_column_name.should == 'pitch' - RenamedColumns.depth_column_name.should == 'pitch' - end - - it "should have parent_column_name" do - Default.parent_column_name.should == 'parent_id' - Default.new.parent_column_name.should == 'parent_id' - RenamedColumns.parent_column_name.should == 'mother_id' - RenamedColumns.new.parent_column_name.should == 'mother_id' - end - end - - it "creation_with_altered_column_names" do - lambda { - RenamedColumns.create!() - }.should_not raise_exception - end - - it "creation when existing record has nil left column" do - assert_nothing_raised do - Broken.create! - end - end - - it "quoted_left_column_name" do - quoted = Default.connection.quote_column_name('lft') - Default.quoted_left_column_name.should == quoted - Default.new.quoted_left_column_name.should == quoted - end - - it "quoted_right_column_name" do - quoted = Default.connection.quote_column_name('rgt') - Default.quoted_right_column_name.should == quoted - Default.new.quoted_right_column_name.should == quoted - end - - it "quoted_depth_column_name" do - quoted = Default.connection.quote_column_name('depth') - Default.quoted_depth_column_name.should == quoted - Default.new.quoted_depth_column_name.should == quoted - end - - it "quoted_order_column_name" do - quoted = Default.connection.quote_column_name('lft') - Default.quoted_order_column_name.should == quoted - Default.new.quoted_order_column_name.should == quoted - end - - it "left_column_protected_from_assignment" do - lambda { - Category.new.lft = 1 - }.should raise_exception(ActiveRecord::ActiveRecordError) - end - - it "right_column_protected_from_assignment" do - lambda { - Category.new.rgt = 1 - }.should raise_exception(ActiveRecord::ActiveRecordError) - end - - it "depth_column_protected_from_assignment" do - lambda { - Category.new.depth = 1 - }.should raise_exception(ActiveRecord::ActiveRecordError) - end - - it "scoped_appends_id" do - ScopedCategory.acts_as_nested_set_options[:scope].should == :organization_id - end - - it "roots_class_method" do - found_by_us = Category.where(:parent_id => nil).to_a - found_by_roots = Category.roots.to_a - found_by_us.length.should == found_by_roots.length - found_by_us.each do |root| - found_by_roots.should include(root) - end - end - - it "root_class_method" do - Category.root.should == categories(:top_level) - end - - it "root" do - categories(:child_3).root.should == categories(:top_level) - end - - it "root when not persisted and parent_column_name value is self" do - new_category = Category.new - new_category.root.should == new_category - end - - it "root when not persisted and parent_column_name value is set" do - last_category = Category.last - Category.new(Default.parent_column_name => last_category.id).root.should == last_category.root - end - - it "root?" do - categories(:top_level).root?.should be_true - categories(:top_level_2).root?.should be_true - end - - it "leaves_class_method" do - Category.leaves.count.should == 4 - Category.leaves.should include(categories(:child_1)) - Category.leaves.should include(categories(:child_2_1)) - Category.leaves.should include(categories(:child_3)) - Category.leaves.should include(categories(:top_level_2)) - end - - it "leaf" do - categories(:child_1).leaf?.should be_true - categories(:child_2_1).leaf?.should be_true - categories(:child_3).leaf?.should be_true - categories(:top_level_2).leaf?.should be_true - - categories(:top_level).leaf?.should be_false - categories(:child_2).leaf?.should be_false - Category.new.leaf?.should be_false - end - - - it "parent" do - categories(:child_2_1).parent.should == categories(:child_2) - end - - it "self_and_ancestors" do - child = categories(:child_2_1) - self_and_ancestors = [categories(:top_level), categories(:child_2), child] - child.self_and_ancestors.should == self_and_ancestors - end - - it "ancestors" do - child = categories(:child_2_1) - ancestors = [categories(:top_level), categories(:child_2)] - ancestors.should == child.ancestors - end - - it "self_and_siblings" do - child = categories(:child_2) - self_and_siblings = [categories(:child_1), child, categories(:child_3)] - self_and_siblings.should == child.self_and_siblings - lambda do - tops = [categories(:top_level), categories(:top_level_2)] - assert_equal tops, categories(:top_level).self_and_siblings - end.should_not raise_exception - end - - it "siblings" do - child = categories(:child_2) - siblings = [categories(:child_1), categories(:child_3)] - siblings.should == child.siblings - end - - it "leaves" do - leaves = [categories(:child_1), categories(:child_2_1), categories(:child_3)] - categories(:top_level).leaves.should == leaves - end - - describe "level" do - it "returns the correct level" do - categories(:top_level).level.should == 0 - categories(:child_1).level.should == 1 - categories(:child_2_1).level.should == 2 - end - - context "given parent associations are loaded" do - it "returns the correct level" do - child = categories(:child_1) - if child.respond_to?(:association) - child.association(:parent).load_target - child.parent.association(:parent).load_target - child.level.should == 1 - else - pending 'associations not used where child#association is not a method' - end - end - end - end - - describe "depth" do - let(:lawyers) { Category.create!(:name => "lawyers") } - let(:us) { Category.create!(:name => "United States") } - let(:new_york) { Category.create!(:name => "New York") } - let(:patent) { Category.create!(:name => "Patent Law") } - - before(:each) do - # lawyers > us > new_york > patent - us.move_to_child_of(lawyers) - new_york.move_to_child_of(us) - patent.move_to_child_of(new_york) - [lawyers, us, new_york, patent].each(&:reload) - end - - it "updates depth when moved into child position" do - lawyers.depth.should == 0 - us.depth.should == 1 - new_york.depth.should == 2 - patent.depth.should == 3 - end - - it "updates depth of all descendants when parent is moved" do - # lawyers - # us > new_york > patent - us.move_to_right_of(lawyers) - [lawyers, us, new_york, patent].each(&:reload) - us.depth.should == 0 - new_york.depth.should == 1 - patent.depth.should == 2 - end - end - - it "depth is magic and does not apply when column is missing" do - lambda { NoDepth.create!(:name => "shallow") }.should_not raise_error - lambda { NoDepth.first.save }.should_not raise_error - lambda { NoDepth.rebuild! }.should_not raise_error - - NoDepth.method_defined?(:depth).should be_false - NoDepth.first.respond_to?(:depth).should be_false - end - - it "has_children?" do - categories(:child_2_1).children.empty?.should be_true - categories(:child_2).children.empty?.should be_false - categories(:top_level).children.empty?.should be_false - end - - it "self_and_descendants" do - parent = categories(:top_level) - self_and_descendants = [ - parent, - categories(:child_1), - categories(:child_2), - categories(:child_2_1), - categories(:child_3) - ] - self_and_descendants.should == parent.self_and_descendants - self_and_descendants.count.should == parent.self_and_descendants.count - end - - it "descendants" do - lawyers = Category.create!(:name => "lawyers") - us = Category.create!(:name => "United States") - us.move_to_child_of(lawyers) - patent = Category.create!(:name => "Patent Law") - patent.move_to_child_of(us) - lawyers.reload - - lawyers.children.size.should == 1 - us.children.size.should == 1 - lawyers.descendants.size.should == 2 - end - - it "self_and_descendants" do - parent = categories(:top_level) - descendants = [ - categories(:child_1), - categories(:child_2), - categories(:child_2_1), - categories(:child_3) - ] - descendants.should == parent.descendants - end - - it "children" do - category = categories(:top_level) - category.children.each {|c| category.id.should == c.parent_id } - end - - it "order_of_children" do - categories(:child_2).move_left - categories(:child_2).should == categories(:top_level).children[0] - categories(:child_1).should == categories(:top_level).children[1] - categories(:child_3).should == categories(:top_level).children[2] - end - - it "is_or_is_ancestor_of?" do - categories(:top_level).is_or_is_ancestor_of?(categories(:child_1)).should be_true - categories(:top_level).is_or_is_ancestor_of?(categories(:child_2_1)).should be_true - categories(:child_2).is_or_is_ancestor_of?(categories(:child_2_1)).should be_true - categories(:child_2_1).is_or_is_ancestor_of?(categories(:child_2)).should be_false - categories(:child_1).is_or_is_ancestor_of?(categories(:child_2)).should be_false - categories(:child_1).is_or_is_ancestor_of?(categories(:child_1)).should be_true - end - - it "is_ancestor_of?" do - categories(:top_level).is_ancestor_of?(categories(:child_1)).should be_true - categories(:top_level).is_ancestor_of?(categories(:child_2_1)).should be_true - categories(:child_2).is_ancestor_of?(categories(:child_2_1)).should be_true - categories(:child_2_1).is_ancestor_of?(categories(:child_2)).should be_false - categories(:child_1).is_ancestor_of?(categories(:child_2)).should be_false - categories(:child_1).is_ancestor_of?(categories(:child_1)).should be_false - end - - it "is_or_is_ancestor_of_with_scope" do - root = ScopedCategory.root - child = root.children.first - root.is_or_is_ancestor_of?(child).should be_true - child.update_attribute :organization_id, 'different' - root.is_or_is_ancestor_of?(child).should be_false - end - - it "is_or_is_descendant_of?" do - categories(:child_1).is_or_is_descendant_of?(categories(:top_level)).should be_true - categories(:child_2_1).is_or_is_descendant_of?(categories(:top_level)).should be_true - categories(:child_2_1).is_or_is_descendant_of?(categories(:child_2)).should be_true - categories(:child_2).is_or_is_descendant_of?(categories(:child_2_1)).should be_false - categories(:child_2).is_or_is_descendant_of?(categories(:child_1)).should be_false - categories(:child_1).is_or_is_descendant_of?(categories(:child_1)).should be_true - end - - it "is_descendant_of?" do - categories(:child_1).is_descendant_of?(categories(:top_level)).should be_true - categories(:child_2_1).is_descendant_of?(categories(:top_level)).should be_true - categories(:child_2_1).is_descendant_of?(categories(:child_2)).should be_true - categories(:child_2).is_descendant_of?(categories(:child_2_1)).should be_false - categories(:child_2).is_descendant_of?(categories(:child_1)).should be_false - categories(:child_1).is_descendant_of?(categories(:child_1)).should be_false - end - - it "is_or_is_descendant_of_with_scope" do - root = ScopedCategory.root - child = root.children.first - child.is_or_is_descendant_of?(root).should be_true - child.update_attribute :organization_id, 'different' - child.is_or_is_descendant_of?(root).should be_false - end - - it "same_scope?" do - root = ScopedCategory.root - child = root.children.first - child.same_scope?(root).should be_true - child.update_attribute :organization_id, 'different' - child.same_scope?(root).should be_false - end - - it "left_sibling" do - categories(:child_1).should == categories(:child_2).left_sibling - categories(:child_2).should == categories(:child_3).left_sibling - end - - it "left_sibling_of_root" do - categories(:top_level).left_sibling.should be_nil - end - - it "left_sibling_without_siblings" do - categories(:child_2_1).left_sibling.should be_nil - end - - it "left_sibling_of_leftmost_node" do - categories(:child_1).left_sibling.should be_nil - end - - it "right_sibling" do - categories(:child_3).should == categories(:child_2).right_sibling - categories(:child_2).should == categories(:child_1).right_sibling - end - - it "right_sibling_of_root" do - categories(:top_level_2).should == categories(:top_level).right_sibling - categories(:top_level_2).right_sibling.should be_nil - end - - it "right_sibling_without_siblings" do - categories(:child_2_1).right_sibling.should be_nil - end - - it "right_sibling_of_rightmost_node" do - categories(:child_3).right_sibling.should be_nil - end - - it "move_left" do - categories(:child_2).move_left - categories(:child_2).left_sibling.should be_nil - categories(:child_1).should == categories(:child_2).right_sibling - Category.valid?.should be_true - end - - it "move_right" do - categories(:child_2).move_right - categories(:child_2).right_sibling.should be_nil - categories(:child_3).should == categories(:child_2).left_sibling - Category.valid?.should be_true - end - - it "move_to_left_of" do - categories(:child_3).move_to_left_of(categories(:child_1)) - categories(:child_3).left_sibling.should be_nil - categories(:child_1).should == categories(:child_3).right_sibling - Category.valid?.should be_true - end - - it "move_to_right_of" do - categories(:child_1).move_to_right_of(categories(:child_3)) - categories(:child_1).right_sibling.should be_nil - categories(:child_3).should == categories(:child_1).left_sibling - Category.valid?.should be_true - end - - it "move_to_root" do - categories(:child_2).move_to_root - categories(:child_2).parent.should be_nil - categories(:child_2).level.should == 0 - categories(:child_2_1).level.should == 1 - categories(:child_2).left.should == 7 - categories(:child_2).right.should == 10 - Category.valid?.should be_true - end - - it "move_to_child_of" do - categories(:child_1).move_to_child_of(categories(:child_3)) - categories(:child_3).id.should == categories(:child_1).parent_id - Category.valid?.should be_true - end - - describe "#move_to_child_with_index" do - it "move to a node without child" do - categories(:child_1).move_to_child_with_index(categories(:child_3), 0) - categories(:child_3).id.should == categories(:child_1).parent_id - categories(:child_1).left.should == 7 - categories(:child_1).right.should == 8 - categories(:child_3).left.should == 6 - categories(:child_3).right.should == 9 - Category.valid?.should be_true - end - - it "move to a node to the left child" do - categories(:child_1).move_to_child_with_index(categories(:child_2), 0) - categories(:child_1).parent_id.should == categories(:child_2).id - categories(:child_2_1).left.should == 5 - categories(:child_2_1).right.should == 6 - categories(:child_1).left.should == 3 - categories(:child_1).right.should == 4 - categories(:child_2).reload - categories(:child_2).left.should == 2 - categories(:child_2).right.should == 7 - end - - it "move to a node to the right child" do - categories(:child_1).move_to_child_with_index(categories(:child_2), 1) - categories(:child_1).parent_id.should == categories(:child_2).id - categories(:child_2_1).left.should == 3 - categories(:child_2_1).right.should == 4 - categories(:child_1).left.should == 5 - categories(:child_1).right.should == 6 - categories(:child_2).reload - categories(:child_2).left.should == 2 - categories(:child_2).right.should == 7 - end - - end - - it "move_to_child_of_appends_to_end" do - child = Category.create! :name => 'New Child' - child.move_to_child_of categories(:top_level) - child.should == categories(:top_level).children.last - end - - it "subtree_move_to_child_of" do - categories(:child_2).left.should == 4 - categories(:child_2).right.should == 7 - - categories(:child_1).left.should == 2 - categories(:child_1).right.should == 3 - - categories(:child_2).move_to_child_of(categories(:child_1)) - Category.valid?.should be_true - categories(:child_1).id.should == categories(:child_2).parent_id - - categories(:child_2).left.should == 3 - categories(:child_2).right.should == 6 - categories(:child_1).left.should == 2 - categories(:child_1).right.should == 7 - end - - it "slightly_difficult_move_to_child_of" do - categories(:top_level_2).left.should == 11 - categories(:top_level_2).right.should == 12 - - # create a new top-level node and move single-node top-level tree inside it. - new_top = Category.create(:name => 'New Top') - new_top.left.should == 13 - new_top.right.should == 14 - - categories(:top_level_2).move_to_child_of(new_top) - - Category.valid?.should be_true - new_top.id.should == categories(:top_level_2).parent_id - - categories(:top_level_2).left.should == 12 - categories(:top_level_2).right.should == 13 - new_top.left.should == 11 - new_top.right.should == 14 - end - - it "difficult_move_to_child_of" do - categories(:top_level).left.should == 1 - categories(:top_level).right.should == 10 - categories(:child_2_1).left.should == 5 - categories(:child_2_1).right.should == 6 - - # create a new top-level node and move an entire top-level tree inside it. - new_top = Category.create(:name => 'New Top') - categories(:top_level).move_to_child_of(new_top) - categories(:child_2_1).reload - Category.valid?.should be_true - new_top.id.should == categories(:top_level).parent_id - - categories(:top_level).left.should == 4 - categories(:top_level).right.should == 13 - categories(:child_2_1).left.should == 8 - categories(:child_2_1).right.should == 9 - end - - #rebuild swaps the position of the 2 children when added using move_to_child twice onto same parent - it "move_to_child_more_than_once_per_parent_rebuild" do - root1 = Category.create(:name => 'Root1') - root2 = Category.create(:name => 'Root2') - root3 = Category.create(:name => 'Root3') - - root2.move_to_child_of root1 - root3.move_to_child_of root1 - - output = Category.roots.last.to_text - Category.update_all('lft = null, rgt = null') - Category.rebuild! - - Category.roots.last.to_text.should == output - end - - # doing move_to_child twice onto same parent from the furthest right first - it "move_to_child_more_than_once_per_parent_outside_in" do - node1 = Category.create(:name => 'Node-1') - node2 = Category.create(:name => 'Node-2') - node3 = Category.create(:name => 'Node-3') - - node2.move_to_child_of node1 - node3.move_to_child_of node1 - - output = Category.roots.last.to_text - Category.update_all('lft = null, rgt = null') - Category.rebuild! - - Category.roots.last.to_text.should == output - end - - it "should_move_to_ordered_child" do - node1 = Category.create(:name => 'Node-1') - node2 = Category.create(:name => 'Node-2') - node3 = Category.create(:name => 'Node-3') - - node2.move_to_ordered_child_of(node1, "name") - - assert_equal node1, node2.parent - assert_equal 1, node1.children.count - - node3.move_to_ordered_child_of(node1, "name", true) # acending - - assert_equal node1, node3.parent - assert_equal 2, node1.children.count - assert_equal node2.name, node1.children[0].name - assert_equal node3.name, node1.children[1].name - - node3.move_to_ordered_child_of(node1, "name", false) # decending - node1.reload - - assert_equal node1, node3.parent - assert_equal 2, node1.children.count - assert_equal node3.name, node1.children[0].name - assert_equal node2.name, node1.children[1].name - end - - it "should be able to rebuild without validating each record" do - root1 = Category.create(:name => 'Root1') - root2 = Category.create(:name => 'Root2') - root3 = Category.create(:name => 'Root3') - - root2.move_to_child_of root1 - root3.move_to_child_of root1 - - root2.name = nil - root2.save!(:validate => false) - - output = Category.roots.last.to_text - Category.update_all('lft = null, rgt = null') - Category.rebuild!(false) - - Category.roots.last.to_text.should == output - end - - it "valid_with_null_lefts" do - Category.valid?.should be_true - Category.update_all('lft = null') - Category.valid?.should be_false - end - - it "valid_with_null_rights" do - Category.valid?.should be_true - Category.update_all('rgt = null') - Category.valid?.should be_false - end - - it "valid_with_missing_intermediate_node" do - # Even though child_2_1 will still exist, it is a sign of a sloppy delete, not an invalid tree. - Category.valid?.should be_true - Category.delete(categories(:child_2).id) - Category.valid?.should be_true - end - - it "valid_with_overlapping_and_rights" do - Category.valid?.should be_true - categories(:top_level_2)['lft'] = 0 - categories(:top_level_2).save - Category.valid?.should be_false - end - - it "rebuild" do - Category.valid?.should be_true - before_text = Category.root.to_text - Category.update_all('lft = null, rgt = null') - Category.rebuild! - Category.valid?.should be_true - before_text.should == Category.root.to_text - end - - it "move_possible_for_sibling" do - categories(:child_2).move_possible?(categories(:child_1)).should be_true - end - - it "move_not_possible_to_self" do - categories(:top_level).move_possible?(categories(:top_level)).should be_false - end - - it "move_not_possible_to_parent" do - categories(:top_level).descendants.each do |descendant| - categories(:top_level).move_possible?(descendant).should be_false - descendant.move_possible?(categories(:top_level)).should be_true - end - end - - it "is_or_is_ancestor_of?" do - [:child_1, :child_2, :child_2_1, :child_3].each do |c| - categories(:top_level).is_or_is_ancestor_of?(categories(c)).should be_true - end - categories(:top_level).is_or_is_ancestor_of?(categories(:top_level_2)).should be_false - end - - it "left_and_rights_valid_with_blank_left" do - Category.left_and_rights_valid?.should be_true - categories(:child_2)[:lft] = nil - categories(:child_2).save(:validate => false) - Category.left_and_rights_valid?.should be_false - end - - it "left_and_rights_valid_with_blank_right" do - Category.left_and_rights_valid?.should be_true - categories(:child_2)[:rgt] = nil - categories(:child_2).save(:validate => false) - Category.left_and_rights_valid?.should be_false - end - - it "left_and_rights_valid_with_equal" do - Category.left_and_rights_valid?.should be_true - categories(:top_level_2)[:lft] = categories(:top_level_2)[:rgt] - categories(:top_level_2).save(:validate => false) - Category.left_and_rights_valid?.should be_false - end - - it "left_and_rights_valid_with_left_equal_to_parent" do - Category.left_and_rights_valid?.should be_true - categories(:child_2)[:lft] = categories(:top_level)[:lft] - categories(:child_2).save(:validate => false) - Category.left_and_rights_valid?.should be_false - end - - it "left_and_rights_valid_with_right_equal_to_parent" do - Category.left_and_rights_valid?.should be_true - categories(:child_2)[:rgt] = categories(:top_level)[:rgt] - categories(:child_2).save(:validate => false) - Category.left_and_rights_valid?.should be_false - end - - it "moving_dirty_objects_doesnt_invalidate_tree" do - r1 = Category.create :name => "Test 1" - r2 = Category.create :name => "Test 2" - r3 = Category.create :name => "Test 3" - r4 = Category.create :name => "Test 4" - nodes = [r1, r2, r3, r4] - - r2.move_to_child_of(r1) - Category.valid?.should be_true - - r3.move_to_child_of(r1) - Category.valid?.should be_true - - r4.move_to_child_of(r2) - Category.valid?.should be_true - end - - it "multi_scoped_no_duplicates_for_columns?" do - lambda { - Note.no_duplicates_for_columns? - }.should_not raise_exception - end - - it "multi_scoped_all_roots_valid?" do - lambda { - Note.all_roots_valid? - }.should_not raise_exception - end - - it "multi_scoped" do - note1 = Note.create!(:body => "A", :notable_id => 2, :notable_type => 'Category') - note2 = Note.create!(:body => "B", :notable_id => 2, :notable_type => 'Category') - note3 = Note.create!(:body => "C", :notable_id => 2, :notable_type => 'Default') - - [note1, note2].should == note1.self_and_siblings - [note3].should == note3.self_and_siblings - end - - it "multi_scoped_rebuild" do - root = Note.create!(:body => "A", :notable_id => 3, :notable_type => 'Category') - child1 = Note.create!(:body => "B", :notable_id => 3, :notable_type => 'Category') - child2 = Note.create!(:body => "C", :notable_id => 3, :notable_type => 'Category') - - child1.move_to_child_of root - child2.move_to_child_of root - - Note.update_all('lft = null, rgt = null') - Note.rebuild! - - Note.roots.find_by_body('A').should == root - [child1, child2].should == Note.roots.find_by_body('A').children - end - - it "same_scope_with_multi_scopes" do - lambda { - notes(:scope1).same_scope?(notes(:child_1)) - }.should_not raise_exception - notes(:scope1).same_scope?(notes(:child_1)).should be_true - notes(:child_1).same_scope?(notes(:scope1)).should be_true - notes(:scope1).same_scope?(notes(:scope2)).should be_false - end - - it "quoting_of_multi_scope_column_names" do - ## Proper Array Assignment for different DBs as per their quoting column behavior - if Note.connection.adapter_name.match(/oracle/i) - expected_quoted_scope_column_names = ["\"NOTABLE_ID\"", "\"NOTABLE_TYPE\""] - elsif Note.connection.adapter_name.match(/mysql/i) - expected_quoted_scope_column_names = ["`notable_id`", "`notable_type`"] - else - expected_quoted_scope_column_names = ["\"notable_id\"", "\"notable_type\""] - end - Note.quoted_scope_column_names.should == expected_quoted_scope_column_names - end - - it "equal_in_same_scope" do - notes(:scope1).should == notes(:scope1) - notes(:scope1).should_not == notes(:child_1) - end - - it "equal_in_different_scopes" do - notes(:scope1).should_not == notes(:scope2) - end - - it "delete_does_not_invalidate" do - Category.acts_as_nested_set_options[:dependent] = :delete - categories(:child_2).destroy - Category.valid?.should be_true - end - - it "destroy_does_not_invalidate" do - Category.acts_as_nested_set_options[:dependent] = :destroy - categories(:child_2).destroy - Category.valid?.should be_true - end - - it "destroy_multiple_times_does_not_invalidate" do - Category.acts_as_nested_set_options[:dependent] = :destroy - categories(:child_2).destroy - categories(:child_2).destroy - Category.valid?.should be_true - end - - it "assigning_parent_id_on_create" do - category = Category.create!(:name => "Child", :parent_id => categories(:child_2).id) - categories(:child_2).should == category.parent - categories(:child_2).id.should == category.parent_id - category.left.should_not be_nil - category.right.should_not be_nil - Category.valid?.should be_true - end - - it "assigning_parent_on_create" do - category = Category.create!(:name => "Child", :parent => categories(:child_2)) - categories(:child_2).should == category.parent - categories(:child_2).id.should == category.parent_id - category.left.should_not be_nil - category.right.should_not be_nil - Category.valid?.should be_true - end - - it "assigning_parent_id_to_nil_on_create" do - category = Category.create!(:name => "New Root", :parent_id => nil) - category.parent.should be_nil - category.parent_id.should be_nil - category.left.should_not be_nil - category.right.should_not be_nil - Category.valid?.should be_true - end - - it "assigning_parent_id_on_update" do - category = categories(:child_2_1) - category.parent_id = categories(:child_3).id - category.save - category.reload - categories(:child_3).reload - categories(:child_3).should == category.parent - categories(:child_3).id.should == category.parent_id - Category.valid?.should be_true - end - - it "assigning_parent_on_update" do - category = categories(:child_2_1) - category.parent = categories(:child_3) - category.save - category.reload - categories(:child_3).reload - categories(:child_3).should == category.parent - categories(:child_3).id.should == category.parent_id - Category.valid?.should be_true - end - - it "assigning_parent_id_to_nil_on_update" do - category = categories(:child_2_1) - category.parent_id = nil - category.save - category.parent.should be_nil - category.parent_id.should be_nil - Category.valid?.should be_true - end - - it "creating_child_from_parent" do - category = categories(:child_2).children.create!(:name => "Child") - categories(:child_2).should == category.parent - categories(:child_2).id.should == category.parent_id - category.left.should_not be_nil - category.right.should_not be_nil - Category.valid?.should be_true - end - - def check_structure(entries, structure) - structure = structure.dup - Category.each_with_level(entries) do |category, level| - expected_level, expected_name = structure.shift - expected_name.should == category.name - expected_level.should == level - end - end - - it "each_with_level" do - levels = [ - [0, "Top Level"], - [1, "Child 1"], - [1, "Child 2"], - [2, "Child 2.1"], - [1, "Child 3" ] - ] - - check_structure(Category.root.self_and_descendants, levels) - - # test some deeper structures - category = Category.find_by_name("Child 1") - c1 = Category.new(:name => "Child 1.1") - c2 = Category.new(:name => "Child 1.1.1") - c3 = Category.new(:name => "Child 1.1.1.1") - c4 = Category.new(:name => "Child 1.2") - [c1, c2, c3, c4].each(&:save!) - - c1.move_to_child_of(category) - c2.move_to_child_of(c1) - c3.move_to_child_of(c2) - c4.move_to_child_of(category) - - levels = [ - [0, "Top Level"], - [1, "Child 1"], - [2, "Child 1.1"], - [3, "Child 1.1.1"], - [4, "Child 1.1.1.1"], - [2, "Child 1.2"], - [1, "Child 2"], - [2, "Child 2.1"], - [1, "Child 3" ] - ] - - check_structure(Category.root.self_and_descendants, levels) - end - - it "should not error on a model with attr_accessible" do - model = Class.new(ActiveRecord::Base) - model.table_name = 'categories' - model.attr_accessible :name - lambda { - model.acts_as_nested_set - model.new(:name => 'foo') - }.should_not raise_exception - end - - describe "before_move_callback" do - it "should fire the callback" do - categories(:child_2).should_receive(:custom_before_move) - categories(:child_2).move_to_root - end - - it "should stop move when callback returns false" do - Category.test_allows_move = false - categories(:child_3).move_to_root.should be_false - categories(:child_3).root?.should be_false - end - - it "should not halt save actions" do - Category.test_allows_move = false - categories(:child_3).parent_id = nil - categories(:child_3).save.should be_true - end - end - - describe "counter_cache" do - - it "should allow use of a counter cache for children" do - note1 = things(:parent1) - note1.children.count.should == 2 - end - - it "should increment the counter cache on create" do - note1 = things(:parent1) - note1.children.count.should == 2 - note1[:children_count].should == 2 - note1.children.create :body => 'Child 3' - note1.children.count.should == 3 - note1.reload - note1[:children_count].should == 3 - end - - it "should decrement the counter cache on destroy" do - note1 = things(:parent1) - note1.children.count.should == 2 - note1[:children_count].should == 2 - note1.children.last.destroy - note1.children.count.should == 1 - note1.reload - note1[:children_count].should == 1 - end - end - - describe "association callbacks on children" do - it "should call the appropriate callbacks on the children :has_many association " do - root = DefaultWithCallbacks.create - root.should_not be_new_record - - child = root.children.build - - root.before_add.should == child - root.after_add.should == child - - root.before_remove.should_not == child - root.after_remove.should_not == child - - child.save.should be_true - root.children.delete(child).should be_true - - root.before_remove.should == child - root.after_remove.should == child - end - end - - describe 'rebuilding tree with a default scope ordering' do - it "doesn't throw exception" do - expect { Position.rebuild! }.not_to raise_error - end - end - - describe 'creating roots with a default scope ordering' do - it "assigns rgt and lft correctly" do - alpha = Order.create(:name => 'Alpha') - gamma = Order.create(:name => 'Gamma') - omega = Order.create(:name => 'Omega') - - alpha.lft.should == 1 - alpha.rgt.should == 2 - gamma.lft.should == 3 - gamma.rgt.should == 4 - omega.lft.should == 5 - omega.rgt.should == 6 - end - end - - describe 'moving node from one scoped tree to another' do - xit "moves single node correctly" do - root1 = Note.create!(:body => "A-1", :notable_id => 4, :notable_type => 'Category') - child1_1 = Note.create!(:body => "B-1", :notable_id => 4, :notable_type => 'Category') - child1_2 = Note.create!(:body => "C-1", :notable_id => 4, :notable_type => 'Category') - child1_1.move_to_child_of root1 - child1_2.move_to_child_of root1 - - root2 = Note.create!(:body => "A-2", :notable_id => 5, :notable_type => 'Category') - child2_1 = Note.create!(:body => "B-2", :notable_id => 5, :notable_type => 'Category') - child2_2 = Note.create!(:body => "C-2", :notable_id => 5, :notable_type => 'Category') - child2_1.move_to_child_of root2 - child2_2.move_to_child_of root2 - - child1_1.update_attributes!(:notable_id => 5) - child1_1.move_to_child_of root2 - - root1.children.should == [child1_2] - root2.children.should == [child2_1, child2_2, child1_1] - - Note.valid?.should == true - end - - xit "moves node with children correctly" do - root1 = Note.create!(:body => "A-1", :notable_id => 4, :notable_type => 'Category') - child1_1 = Note.create!(:body => "B-1", :notable_id => 4, :notable_type => 'Category') - child1_2 = Note.create!(:body => "C-1", :notable_id => 4, :notable_type => 'Category') - child1_1.move_to_child_of root1 - child1_2.move_to_child_of child1_1 - - root2 = Note.create!(:body => "A-2", :notable_id => 5, :notable_type => 'Category') - child2_1 = Note.create!(:body => "B-2", :notable_id => 5, :notable_type => 'Category') - child2_2 = Note.create!(:body => "C-2", :notable_id => 5, :notable_type => 'Category') - child2_1.move_to_child_of root2 - child2_2.move_to_child_of root2 - - child1_1.update_attributes!(:notable_id => 5) - child1_1.move_to_child_of root2 - - root1.children.should == [] - root2.children.should == [child2_1, child2_2, child1_1] - child1_1.children should == [child1_2] - root2.siblings.should == [child2_1, child2_2, child1_1, child1_2] - - Note.valid?.should == true - end - end - - describe 'specifying custom sort column' do - it "should sort by the default sort column" do - Category.order_column.should == 'lft' - end - - it "should sort by custom sort column" do - OrderedCategory.acts_as_nested_set_options[:order_column].should == 'name' - OrderedCategory.order_column.should == 'name' - end - end -end diff --git a/lib/plugins/awesome_nested_set/spec/db/database.yml b/lib/plugins/awesome_nested_set/spec/db/database.yml deleted file mode 100644 index 5218975a4..000000000 --- a/lib/plugins/awesome_nested_set/spec/db/database.yml +++ /dev/null @@ -1,27 +0,0 @@ -sqlite3: - adapter: <%= "jdbc" if defined? JRUBY_VERSION %>sqlite3 - database: awesome_nested_set.sqlite3.db -sqlite3mem: - adapter: <%= "jdbc" if defined? JRUBY_VERSION %>sqlite3 - database: ":memory:" -postgresql: - adapter: postgresql - encoding: unicode - database: awesome_nested_set_plugin_test - pool: 5 - username: postgres - password: postgres - min_messages: warning -mysql: - adapter: mysql2 - host: localhost - username: root - password: - database: awesome_nested_set_plugin_test -## Add DB Configuration to run Oracle tests -oracle: - adapter: oracle_enhanced - host: localhost - username: awesome_nested_set_dev - password: - database: xe diff --git a/lib/plugins/awesome_nested_set/spec/db/schema.rb b/lib/plugins/awesome_nested_set/spec/db/schema.rb deleted file mode 100644 index b37322b14..000000000 --- a/lib/plugins/awesome_nested_set/spec/db/schema.rb +++ /dev/null @@ -1,74 +0,0 @@ -ActiveRecord::Schema.define(:version => 0) do - - create_table :categories, :force => true do |t| - t.column :name, :string - t.column :parent_id, :integer - t.column :lft, :integer - t.column :rgt, :integer - t.column :depth, :integer - t.column :organization_id, :integer - end - - create_table :departments, :force => true do |t| - t.column :name, :string - end - - create_table :notes, :force => true do |t| - t.column :body, :text - t.column :parent_id, :integer - t.column :lft, :integer - t.column :rgt, :integer - t.column :depth, :integer - t.column :notable_id, :integer - t.column :notable_type, :string - end - - create_table :renamed_columns, :force => true do |t| - t.column :name, :string - t.column :mother_id, :integer - t.column :red, :integer - t.column :black, :integer - t.column :pitch, :integer - end - - create_table :things, :force => true do |t| - t.column :body, :text - t.column :parent_id, :integer - t.column :lft, :integer - t.column :rgt, :integer - t.column :depth, :integer - t.column :children_count, :integer - end - - create_table :brokens, :force => true do |t| - t.column :name, :string - t.column :parent_id, :integer - t.column :lft, :integer - t.column :rgt, :integer - t.column :depth, :integer - end - - create_table :orders, :force => true do |t| - t.column :name, :string - t.column :parent_id, :integer - t.column :lft, :integer - t.column :rgt, :integer - t.column :depth, :integer - end - - create_table :positions, :force => true do |t| - t.column :name, :string - t.column :parent_id, :integer - t.column :lft, :integer - t.column :rgt, :integer - t.column :depth, :integer - t.column :position, :integer - end - - create_table :no_depths, :force => true do |t| - t.column :name, :string - t.column :parent_id, :integer - t.column :lft, :integer - t.column :rgt, :integer - end -end diff --git a/lib/plugins/awesome_nested_set/spec/fixtures/brokens.yml b/lib/plugins/awesome_nested_set/spec/fixtures/brokens.yml deleted file mode 100644 index 3cb6ce915..000000000 --- a/lib/plugins/awesome_nested_set/spec/fixtures/brokens.yml +++ /dev/null @@ -1,3 +0,0 @@ -one: - id: 1 - name: One
\ No newline at end of file diff --git a/lib/plugins/awesome_nested_set/spec/fixtures/categories.yml b/lib/plugins/awesome_nested_set/spec/fixtures/categories.yml deleted file mode 100644 index bc8e078e8..000000000 --- a/lib/plugins/awesome_nested_set/spec/fixtures/categories.yml +++ /dev/null @@ -1,34 +0,0 @@ -top_level: - id: 1 - name: Top Level - lft: 1 - rgt: 10 -child_1: - id: 2 - name: Child 1 - parent_id: 1 - lft: 2 - rgt: 3 -child_2: - id: 3 - name: Child 2 - parent_id: 1 - lft: 4 - rgt: 7 -child_2_1: - id: 4 - name: Child 2.1 - parent_id: 3 - lft: 5 - rgt: 6 -child_3: - id: 5 - name: Child 3 - parent_id: 1 - lft: 8 - rgt: 9 -top_level_2: - id: 6 - name: Top Level 2 - lft: 11 - rgt: 12 diff --git a/lib/plugins/awesome_nested_set/spec/fixtures/departments.yml b/lib/plugins/awesome_nested_set/spec/fixtures/departments.yml deleted file mode 100644 index e50a944f1..000000000 --- a/lib/plugins/awesome_nested_set/spec/fixtures/departments.yml +++ /dev/null @@ -1,3 +0,0 @@ -top: - id: 1 - name: Top
\ No newline at end of file diff --git a/lib/plugins/awesome_nested_set/spec/fixtures/notes.yml b/lib/plugins/awesome_nested_set/spec/fixtures/notes.yml deleted file mode 100644 index 004a5335a..000000000 --- a/lib/plugins/awesome_nested_set/spec/fixtures/notes.yml +++ /dev/null @@ -1,38 +0,0 @@ -scope1: - id: 1 - body: Top Level - lft: 1 - rgt: 10 - notable_id: 1 - notable_type: Category -child_1: - id: 2 - body: Child 1 - parent_id: 1 - lft: 2 - rgt: 3 - notable_id: 1 - notable_type: Category -child_2: - id: 3 - body: Child 2 - parent_id: 1 - lft: 4 - rgt: 7 - notable_id: 1 - notable_type: Category -child_3: - id: 4 - body: Child 3 - parent_id: 1 - lft: 8 - rgt: 9 - notable_id: 1 - notable_type: Category -scope2: - id: 5 - body: Top Level 2 - lft: 1 - rgt: 2 - notable_id: 1 - notable_type: Departments diff --git a/lib/plugins/awesome_nested_set/spec/fixtures/things.yml b/lib/plugins/awesome_nested_set/spec/fixtures/things.yml deleted file mode 100644 index 207a682ed..000000000 --- a/lib/plugins/awesome_nested_set/spec/fixtures/things.yml +++ /dev/null @@ -1,27 +0,0 @@ -parent1: - id: 1 - body: Top Level - lft: 1 - rgt: 10 - children_count: 2 -child_1: - id: 2 - body: Child 1 - parent_id: 1 - lft: 2 - rgt: 3 - children_count: 0 -child_2: - id: 3 - body: Child 2 - parent_id: 1 - lft: 4 - rgt: 7 - children_count: 0 -child_2_1: - id: 4 - body: Child 2.1 - parent_id: 3 - lft: 8 - rgt: 9 - children_count: 0 diff --git a/lib/plugins/awesome_nested_set/spec/spec_helper.rb b/lib/plugins/awesome_nested_set/spec/spec_helper.rb deleted file mode 100644 index 2e637bfc8..000000000 --- a/lib/plugins/awesome_nested_set/spec/spec_helper.rb +++ /dev/null @@ -1,35 +0,0 @@ -plugin_test_dir = File.dirname(__FILE__) - -require 'rubygems' -require 'bundler/setup' -require 'pry' - -require 'logger' -require 'active_record' -ActiveRecord::Base.logger = Logger.new(plugin_test_dir + "/debug.log") - -require 'yaml' -require 'erb' -ActiveRecord::Base.configurations = YAML::load(ERB.new(IO.read(plugin_test_dir + "/db/database.yml")).result) -ActiveRecord::Base.establish_connection(ENV["DB"] ||= "sqlite3mem") -ActiveRecord::Migration.verbose = false - -require 'combustion/database' -Combustion::Database.create_database(ActiveRecord::Base.configurations[ENV["DB"]]) -load(File.join(plugin_test_dir, "db", "schema.rb")) - -require 'awesome_nested_set' -require 'support/models' - -require 'action_controller' -require 'rspec/rails' -require 'database_cleaner' -RSpec.configure do |config| - config.fixture_path = "#{plugin_test_dir}/fixtures" - config.use_transactional_fixtures = true - config.after(:suite) do - unless /sqlite/ === ENV['DB'] - Combustion::Database.drop_database(ActiveRecord::Base.configurations[ENV['DB']]) - end - end -end diff --git a/lib/plugins/awesome_nested_set/spec/support/models.rb b/lib/plugins/awesome_nested_set/spec/support/models.rb deleted file mode 100644 index c54ff3e2c..000000000 --- a/lib/plugins/awesome_nested_set/spec/support/models.rb +++ /dev/null @@ -1,96 +0,0 @@ -class Note < ActiveRecord::Base - acts_as_nested_set :scope => [:notable_id, :notable_type] -end - -class Default < ActiveRecord::Base - self.table_name = 'categories' - acts_as_nested_set -end - -class ScopedCategory < ActiveRecord::Base - self.table_name = 'categories' - acts_as_nested_set :scope => :organization -end - -class OrderedCategory < ActiveRecord::Base - self.table_name = 'categories' - acts_as_nested_set :order_column => 'name' -end - -class RenamedColumns < ActiveRecord::Base - acts_as_nested_set :parent_column => 'mother_id', - :left_column => 'red', - :right_column => 'black', - :depth_column => 'pitch' -end - -class Category < ActiveRecord::Base - acts_as_nested_set - - validates_presence_of :name - - # Setup a callback that we can switch to true or false per-test - set_callback :move, :before, :custom_before_move - cattr_accessor :test_allows_move - @@test_allows_move = true - def custom_before_move - @@test_allows_move - end - - def to_s - name - end - - def recurse &block - block.call self, lambda{ - self.children.each do |child| - child.recurse &block - end - } - end -end - -class Thing < ActiveRecord::Base - acts_as_nested_set :counter_cache => 'children_count' -end - -class DefaultWithCallbacks < ActiveRecord::Base - - self.table_name = 'categories' - - attr_accessor :before_add, :after_add, :before_remove, :after_remove - - acts_as_nested_set :before_add => :do_before_add_stuff, - :after_add => :do_after_add_stuff, - :before_remove => :do_before_remove_stuff, - :after_remove => :do_after_remove_stuff - - private - - [ :before_add, :after_add, :before_remove, :after_remove ].each do |hook_name| - define_method "do_#{hook_name}_stuff" do |child_node| - self.send("#{hook_name}=", child_node) - end - end - -end - -class Broken < ActiveRecord::Base - acts_as_nested_set -end - -class Order < ActiveRecord::Base - acts_as_nested_set - - default_scope order(:name) -end - -class Position < ActiveRecord::Base - acts_as_nested_set - - default_scope order(:position) -end - -class NoDepth < ActiveRecord::Base - acts_as_nested_set -end diff --git a/lib/redmine.rb b/lib/redmine.rb index 2e97b0418..9fad74f42 100644 --- a/lib/redmine.rb +++ b/lib/redmine.rb @@ -63,12 +63,7 @@ require 'redmine/themes' require 'redmine/hook' require 'redmine/plugin' -if RUBY_VERSION < '1.9' - require 'fastercsv' -else - require 'csv' - FCSV = CSV -end +require 'csv' Redmine::Scm::Base.add "Subversion" Redmine::Scm::Base.add "Darcs" diff --git a/lib/redmine/access_control.rb b/lib/redmine/access_control.rb index 68de56965..21359508b 100644 --- a/lib/redmine/access_control.rb +++ b/lib/redmine/access_control.rb @@ -58,9 +58,11 @@ module Redmine if action.is_a?(Symbol) perm = permission(action) !perm.nil? && perm.read? - else + elsif action.is_a?(Hash) s = "#{action[:controller]}/#{action[:action]}" permissions.detect {|p| p.actions.include?(s) && p.read?}.present? + else + raise ArgumentError.new("Symbol or a Hash expected, #{action.class.name} given: #{action}") end end diff --git a/lib/redmine/codeset_util.rb b/lib/redmine/codeset_util.rb index 45a5c3524..bb1f972d4 100644 --- a/lib/redmine/codeset_util.rb +++ b/lib/redmine/codeset_util.rb @@ -1,160 +1,71 @@ -if RUBY_VERSION < '1.9' - require 'iconv' -end module Redmine module CodesetUtil def self.replace_invalid_utf8(str) return str if str.nil? - if str.respond_to?(:force_encoding) - str.force_encoding('UTF-8') - if ! str.valid_encoding? - str = str.encode("US-ASCII", :invalid => :replace, - :undef => :replace, :replace => '?').encode("UTF-8") - end - elsif RUBY_PLATFORM == 'java' - begin - ic = Iconv.new('UTF-8', 'UTF-8') - str = ic.iconv(str) - rescue - str = str.gsub(%r{[^\r\n\t\x20-\x7e]}, '?') - end - else - ic = Iconv.new('UTF-8', 'UTF-8') - txtar = "" - begin - txtar += ic.iconv(str) - rescue Iconv::IllegalSequence - txtar += $!.success - str = '?' + $!.failed[1,$!.failed.length] - retry - rescue - txtar += $!.success - end - str = txtar + str.force_encoding('UTF-8') + if ! str.valid_encoding? + str = str.encode("US-ASCII", :invalid => :replace, + :undef => :replace, :replace => '?').encode("UTF-8") end str end def self.to_utf8(str, encoding) return str if str.nil? - str.force_encoding("ASCII-8BIT") if str.respond_to?(:force_encoding) + str.force_encoding("ASCII-8BIT") if str.empty? - str.force_encoding("UTF-8") if str.respond_to?(:force_encoding) + str.force_encoding("UTF-8") return str end enc = encoding.blank? ? "UTF-8" : encoding - if str.respond_to?(:force_encoding) - if enc.upcase != "UTF-8" - str.force_encoding(enc) - str = str.encode("UTF-8", :invalid => :replace, - :undef => :replace, :replace => '?') - else - str.force_encoding("UTF-8") - if ! str.valid_encoding? - str = str.encode("US-ASCII", :invalid => :replace, - :undef => :replace, :replace => '?').encode("UTF-8") - end - end - elsif RUBY_PLATFORM == 'java' - begin - ic = Iconv.new('UTF-8', enc) - str = ic.iconv(str) - rescue - str = str.gsub(%r{[^\r\n\t\x20-\x7e]}, '?') - end + if enc.upcase != "UTF-8" + str.force_encoding(enc) + str = str.encode("UTF-8", :invalid => :replace, + :undef => :replace, :replace => '?') else - ic = Iconv.new('UTF-8', enc) - txtar = "" - begin - txtar += ic.iconv(str) - rescue Iconv::IllegalSequence - txtar += $!.success - str = '?' + $!.failed[1,$!.failed.length] - retry - rescue - txtar += $!.success + str.force_encoding("UTF-8") + if ! str.valid_encoding? + str = str.encode("US-ASCII", :invalid => :replace, + :undef => :replace, :replace => '?').encode("UTF-8") end - str = txtar end str end def self.to_utf8_by_setting(str) return str if str.nil? - str = self.to_utf8_by_setting_internal(str) - if str.respond_to?(:force_encoding) - str.force_encoding('UTF-8') - end - str + self.to_utf8_by_setting_internal(str).force_encoding('UTF-8') end def self.to_utf8_by_setting_internal(str) return str if str.nil? - if str.respond_to?(:force_encoding) - str.force_encoding('ASCII-8BIT') - end + str.force_encoding('ASCII-8BIT') return str if str.empty? return str if /\A[\r\n\t\x20-\x7e]*\Z/n.match(str) # for us-ascii - if str.respond_to?(:force_encoding) - str.force_encoding('UTF-8') - end + str.force_encoding('UTF-8') encodings = Setting.repositories_encodings.split(',').collect(&:strip) encodings.each do |encoding| - if str.respond_to?(:force_encoding) - begin - str.force_encoding(encoding) - utf8 = str.encode('UTF-8') - return utf8 if utf8.valid_encoding? - rescue - # do nothing here and try the next encoding - end - else - begin - return Iconv.conv('UTF-8', encoding, str) - rescue Iconv::Failure - # do nothing here and try the next encoding - end + begin + str.force_encoding(encoding) + utf8 = str.encode('UTF-8') + return utf8 if utf8.valid_encoding? + rescue + # do nothing here and try the next encoding end end - str = self.replace_invalid_utf8(str) - if str.respond_to?(:force_encoding) - str.force_encoding('UTF-8') - end - str + self.replace_invalid_utf8(str).force_encoding('UTF-8') end def self.from_utf8(str, encoding) str ||= '' - if str.respond_to?(:force_encoding) - str.force_encoding('UTF-8') - if encoding.upcase != 'UTF-8' - str = str.encode(encoding, :invalid => :replace, - :undef => :replace, :replace => '?') - else - str = self.replace_invalid_utf8(str) - end - elsif RUBY_PLATFORM == 'java' - begin - ic = Iconv.new(encoding, 'UTF-8') - str = ic.iconv(str) - rescue - str = str.gsub(%r{[^\r\n\t\x20-\x7e]}, '?') - end + str.force_encoding('UTF-8') + if encoding.upcase != 'UTF-8' + str = str.encode(encoding, :invalid => :replace, + :undef => :replace, :replace => '?') else - ic = Iconv.new(encoding, 'UTF-8') - txtar = "" - begin - txtar += ic.iconv(str) - rescue Iconv::IllegalSequence - txtar += $!.success - str = '?' + $!.failed[1, $!.failed.length] - retry - rescue - txtar += $!.success - end - str = txtar + str = self.replace_invalid_utf8(str) end end end diff --git a/lib/redmine/core_ext/active_record.rb b/lib/redmine/core_ext/active_record.rb index 259da2e14..a1135d51d 100644 --- a/lib/redmine/core_ext/active_record.rb +++ b/lib/redmine/core_ext/active_record.rb @@ -15,35 +15,10 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -module ActiveRecord - module FinderMethods - def find_ids(*args) - find_ids_with_associations - end - - private - - def find_ids_with_associations - join_dependency = construct_join_dependency_for_association_find - relation = construct_relation_for_association_find_ids(join_dependency) - rows = connection.select_all(relation, 'SQL', relation.bind_values) - rows.map {|row| row["id"].to_i} - rescue ThrowResult - [] - end - - def construct_relation_for_association_find_ids(join_dependency) - relation = except(:includes, :eager_load, :preload, :select).select("#{table_name}.id") - apply_join_dependency(relation, join_dependency) - end - end -end - class DateValidator < ActiveModel::EachValidator def validate_each(record, attribute, value) before_type_cast = record.attributes_before_type_cast[attribute.to_s] if before_type_cast.is_a?(String) && before_type_cast.present? - # TODO: #*_date_before_type_cast returns a Mysql::Time with ruby1.8+mysql gem unless before_type_cast =~ /\A\d{4}-\d{2}-\d{2}( 00:00:00)?\z/ && value record.errors.add attribute, :not_a_date end diff --git a/lib/redmine/core_ext/string/conversions.rb b/lib/redmine/core_ext/string/conversions.rb index 256f71afa..479f47c10 100644 --- a/lib/redmine/core_ext/string/conversions.rb +++ b/lib/redmine/core_ext/string/conversions.rb @@ -36,13 +36,6 @@ module Redmine #:nodoc: s.gsub!(',', '.') begin; Kernel.Float(s); rescue; nil; end end - - # Object#to_a removed in ruby1.9 - if RUBY_VERSION > '1.9' - def to_a - [self.dup] - end - end end end end diff --git a/lib/redmine/export/pdf.rb b/lib/redmine/export/pdf.rb index b555534a8..9903eaa42 100644 --- a/lib/redmine/export/pdf.rb +++ b/lib/redmine/export/pdf.rb @@ -678,9 +678,7 @@ module Redmine def self.rdm_from_utf8(txt, encoding) txt ||= '' txt = Redmine::CodesetUtil.from_utf8(txt, encoding) - if txt.respond_to?(:force_encoding) - txt.force_encoding('ASCII-8BIT') - end + txt.force_encoding('ASCII-8BIT') txt end diff --git a/lib/redmine/field_format.rb b/lib/redmine/field_format.rb index 18e5d74a8..e1387f2cf 100644 --- a/lib/redmine/field_format.rb +++ b/lib/redmine/field_format.rb @@ -597,18 +597,13 @@ module Redmine def target_class @target_class ||= self.class.name[/^(.*::)?(.+)Format$/, 2].constantize rescue nil end - - def reset_target_class - @target_class = nil - end def possible_custom_value_options(custom_value) options = possible_values_options(custom_value.custom_field, custom_value.customized) missing = [custom_value.value_was].flatten.reject(&:blank?) - options.map(&:last) if missing.any? options += target_class.where(:id => missing.map(&:to_i)).map {|o| [o.to_s, o.id.to_s]} - #TODO: use #sort_by! when ruby1.8 support is dropped - options = options.sort_by(&:first) + options.sort_by!(&:first) end options end diff --git a/lib/redmine/helpers/gantt.rb b/lib/redmine/helpers/gantt.rb index 6b054bb6d..2e4255243 100644 --- a/lib/redmine/helpers/gantt.rb +++ b/lib/redmine/helpers/gantt.rb @@ -167,7 +167,7 @@ module Redmine where("child.id IN (?)", ids). order("#{Project.table_name}.lft ASC"). uniq. - all + to_a else @projects = [] end diff --git a/lib/redmine/menu_manager.rb b/lib/redmine/menu_manager.rb index 18759f26b..8dfd95abe 100644 --- a/lib/redmine/menu_manager.rb +++ b/lib/redmine/menu_manager.rb @@ -193,7 +193,7 @@ module Redmine # * Checking the url target (project only) # * Checking the conditions of the item def allowed_node?(node, user, project) - if project && user && !user.allowed_to?(node.url, project) + if node.url.is_a?(Hash) && project && user && !user.allowed_to?(node.url, project) return false end if node.condition && !node.condition.call(project) diff --git a/lib/redmine/scm/adapters/abstract_adapter.rb b/lib/redmine/scm/adapters/abstract_adapter.rb index ec168bf84..0e60de610 100644 --- a/lib/redmine/scm/adapters/abstract_adapter.rb +++ b/lib/redmine/scm/adapters/abstract_adapter.rb @@ -18,17 +18,13 @@ require 'cgi' require 'redmine/scm/adapters' -if RUBY_VERSION < '1.9' - require 'iconv' -end - module Redmine module Scm module Adapters class AbstractAdapter #:nodoc: # raised if scm command exited with error, e.g. unknown revision. - class ScmCommandAborted < CommandFailed; end + class ScmCommandAborted < ::Redmine::Scm::Adapters::CommandFailed; end class << self def client_command @@ -288,21 +284,12 @@ module Redmine def scm_iconv(to, from, str) return nil if str.nil? return str if to == from - if str.respond_to?(:force_encoding) - str.force_encoding(from) - begin - str.encode(to) - rescue Exception => err - logger.error("failed to convert from #{from} to #{to}. #{err}") - nil - end - else - begin - Iconv.conv(to, from, str) - rescue Iconv::Failure => err - logger.error("failed to convert from #{from} to #{to}. #{err}") - nil - end + str.force_encoding(from) + begin + str.encode(to) + rescue Exception => err + logger.error("failed to convert from #{from} to #{to}. #{err}") + nil end end diff --git a/lib/redmine/scm/adapters/bazaar_adapter.rb b/lib/redmine/scm/adapters/bazaar_adapter.rb index 93ac13e02..c5e9d124d 100644 --- a/lib/redmine/scm/adapters/bazaar_adapter.rb +++ b/lib/redmine/scm/adapters/bazaar_adapter.rb @@ -43,10 +43,7 @@ module Redmine end def scm_command_version - scm_version = scm_version_from_command_line.dup - if scm_version.respond_to?(:force_encoding) - scm_version.force_encoding('ASCII-8BIT') - end + scm_version = scm_version_from_command_line.dup.force_encoding('ASCII-8BIT') if m = scm_version.match(%r{\A(.*?)((\d+\.)+\d+)}) m[2].scan(%r{\d+}).collect(&:to_i) end @@ -100,7 +97,7 @@ module Redmine prefix_utf8 = "#{url}/#{path}".gsub('\\', '/') logger.debug "PREFIX: #{prefix_utf8}" prefix = scm_iconv(@path_encoding, 'UTF-8', prefix_utf8) - prefix.force_encoding('ASCII-8BIT') if prefix.respond_to?(:force_encoding) + prefix.force_encoding('ASCII-8BIT') re = %r{^V\s+(#{Regexp.escape(prefix)})?(\/?)([^\/]+)(\/?)\s+(\S+)\r?$} io.each_line do |line| next unless line =~ re diff --git a/lib/redmine/scm/adapters/cvs_adapter.rb b/lib/redmine/scm/adapters/cvs_adapter.rb index d1096e725..ec7ce7bcf 100644 --- a/lib/redmine/scm/adapters/cvs_adapter.rb +++ b/lib/redmine/scm/adapters/cvs_adapter.rb @@ -43,10 +43,7 @@ module Redmine end def scm_command_version - scm_version = scm_version_from_command_line.dup - if scm_version.respond_to?(:force_encoding) - scm_version.force_encoding('ASCII-8BIT') - end + scm_version = scm_version_from_command_line.dup.force_encoding('ASCII-8BIT') if m = scm_version.match(%r{\A(.*?)((\d+\.)+\d+)}m) m[2].scan(%r{\d+}).collect(&:to_i) end @@ -94,7 +91,7 @@ module Redmine def entries(path=nil, identifier=nil, options={}) logger.debug "<cvs> entries '#{path}' with identifier '#{identifier}'" path_locale = scm_iconv(@path_encoding, 'UTF-8', path) - path_locale.force_encoding("ASCII-8BIT") if path_locale.respond_to?(:force_encoding) + path_locale.force_encoding("ASCII-8BIT") entries = Entries.new cmd_args = %w|-q rls -e| cmd_args << "-D" << time_to_cvstime_rlog(identifier) if identifier @@ -171,6 +168,7 @@ module Redmine file_state = nil branch_map = nil io.each_line() do |line| + line = line.strip if state != "revision" && /^#{ENDLOG}/ =~ line commit_log = String.new revision = nil diff --git a/lib/redmine/scm/adapters/darcs_adapter.rb b/lib/redmine/scm/adapters/darcs_adapter.rb index 3e4d55265..e2807352d 100644 --- a/lib/redmine/scm/adapters/darcs_adapter.rb +++ b/lib/redmine/scm/adapters/darcs_adapter.rb @@ -43,10 +43,7 @@ module Redmine end def darcs_binary_version - darcsversion = darcs_binary_version_from_command_line.dup - if darcsversion.respond_to?(:force_encoding) - darcsversion.force_encoding('ASCII-8BIT') - end + darcsversion = darcs_binary_version_from_command_line.dup.force_encoding('ASCII-8BIT') if m = darcsversion.match(%r{\A(.*?)((\d+\.)+\d+)}) m[2].scan(%r{\d+}).collect(&:to_i) end diff --git a/lib/redmine/scm/adapters/git_adapter.rb b/lib/redmine/scm/adapters/git_adapter.rb index 284a3f401..7a6a590b9 100644 --- a/lib/redmine/scm/adapters/git_adapter.rb +++ b/lib/redmine/scm/adapters/git_adapter.rb @@ -47,10 +47,7 @@ module Redmine end def scm_command_version - scm_version = scm_version_from_command_line.dup - if scm_version.respond_to?(:force_encoding) - scm_version.force_encoding('ASCII-8BIT') - end + scm_version = scm_version_from_command_line.dup.force_encoding('ASCII-8BIT') if m = scm_version.match(%r{\A(.*?)((\d+\.)+\d+)}) m[2].scan(%r{\d+}).collect(&:to_i) end @@ -145,10 +142,7 @@ module Redmine type = $1 sha = $2 size = $3 - name = $4 - if name.respond_to?(:force_encoding) - name.force_encoding(@path_encoding) - end + name = $4.force_encoding(@path_encoding) full_path = p.empty? ? name : "#{p}/#{name}" n = scm_iconv('UTF-8', @path_encoding, name) full_p = scm_iconv('UTF-8', @path_encoding, full_path) diff --git a/lib/redmine/scm/adapters/mercurial_adapter.rb b/lib/redmine/scm/adapters/mercurial_adapter.rb index 881fdc89c..c6aa388a7 100644 --- a/lib/redmine/scm/adapters/mercurial_adapter.rb +++ b/lib/redmine/scm/adapters/mercurial_adapter.rb @@ -54,10 +54,7 @@ module Redmine # The hg version is expressed either as a # release number (eg 0.9.5 or 1.0) or as a revision # id composed of 12 hexa characters. - theversion = hgversion_from_command_line.dup - if theversion.respond_to?(:force_encoding) - theversion.force_encoding('ASCII-8BIT') - end + theversion = hgversion_from_command_line.dup.force_encoding('ASCII-8BIT') if m = theversion.match(%r{\A(.*?)((\d+\.)+\d+)}) m[2].scan(%r{\d+}).collect(&:to_i) end @@ -130,10 +127,7 @@ module Redmine def summary return @summary if @summary hg 'rhsummary' do |io| - output = io.read - if output.respond_to?(:force_encoding) - output.force_encoding('UTF-8') - end + output = io.read.force_encoding('UTF-8') begin @summary = parse_xml(output)['rhsummary'] rescue @@ -146,10 +140,7 @@ module Redmine p1 = scm_iconv(@path_encoding, 'UTF-8', path) manifest = hg('rhmanifest', '-r', CGI.escape(hgrev(identifier)), CGI.escape(without_leading_slash(p1.to_s))) do |io| - output = io.read - if output.respond_to?(:force_encoding) - output.force_encoding('UTF-8') - end + output = io.read.force_encoding('UTF-8') begin parse_xml(output)['rhmanifest']['repository']['manifest'] rescue @@ -193,10 +184,7 @@ module Redmine hg_args << '--limit' << options[:limit] if options[:limit] hg_args << hgtarget(path) unless path.blank? log = hg(*hg_args) do |io| - output = io.read - if output.respond_to?(:force_encoding) - output.force_encoding('UTF-8') - end + output = io.read.force_encoding('UTF-8') begin # Mercurial < 1.5 does not support footer template for '</log>' parse_xml("#{output}</log>")['log'] @@ -278,7 +266,7 @@ module Redmine blame = Annotate.new hg 'rhannotate', '-ncu', '-r', CGI.escape(hgrev(identifier)), hgtarget(p) do |io| io.each_line do |line| - line.force_encoding('ASCII-8BIT') if line.respond_to?(:force_encoding) + line.force_encoding('ASCII-8BIT') next unless line =~ %r{^([^:]+)\s(\d+)\s([0-9a-f]+):\s(.*)$} r = Revision.new(:author => $1.strip, :revision => $2, :scmid => $3, :identifier => $3) diff --git a/lib/redmine/scm/adapters/subversion_adapter.rb b/lib/redmine/scm/adapters/subversion_adapter.rb index fcc9be90d..30ebc0c18 100644 --- a/lib/redmine/scm/adapters/subversion_adapter.rb +++ b/lib/redmine/scm/adapters/subversion_adapter.rb @@ -46,10 +46,7 @@ module Redmine end def svn_binary_version - scm_version = scm_version_from_command_line.dup - if scm_version.respond_to?(:force_encoding) - scm_version.force_encoding('ASCII-8BIT') - end + scm_version = scm_version_from_command_line.dup.force_encoding('ASCII-8BIT') if m = scm_version.match(%r{\A(.*?)((\d+\.)+\d+)}) m[2].scan(%r{\d+}).collect(&:to_i) end @@ -66,10 +63,7 @@ module Redmine cmd << credentials_string info = nil shellout(cmd) do |io| - output = io.read - if output.respond_to?(:force_encoding) - output.force_encoding('UTF-8') - end + output = io.read.force_encoding('UTF-8') begin doc = parse_xml(output) # root_url = doc.elements["info/entry/repository/root"].text @@ -98,10 +92,7 @@ module Redmine cmd = "#{self.class.sq_bin} list --xml #{target(path)}@#{identifier}" cmd << credentials_string shellout(cmd) do |io| - output = io.read - if output.respond_to?(:force_encoding) - output.force_encoding('UTF-8') - end + output = io.read.force_encoding('UTF-8') begin doc = parse_xml(output) each_xml_element(doc['lists']['list'], 'entry') do |entry| @@ -141,10 +132,7 @@ module Redmine cmd << credentials_string properties = {} shellout(cmd) do |io| - output = io.read - if output.respond_to?(:force_encoding) - output.force_encoding('UTF-8') - end + output = io.read.force_encoding('UTF-8') begin doc = parse_xml(output) each_xml_element(doc['properties']['target'], 'property') do |property| @@ -168,10 +156,7 @@ module Redmine cmd << " --limit #{options[:limit].to_i}" if options[:limit] cmd << ' ' + target(path) shellout(cmd) do |io| - output = io.read - if output.respond_to?(:force_encoding) - output.force_encoding('UTF-8') - end + output = io.read.force_encoding('UTF-8') begin doc = parse_xml(output) each_xml_element(doc['log'], 'logentry') do |logentry| diff --git a/lib/redmine/unified_diff.rb b/lib/redmine/unified_diff.rb index ee4ac6987..b40205909 100644 --- a/lib/redmine/unified_diff.rb +++ b/lib/redmine/unified_diff.rb @@ -199,28 +199,10 @@ module Redmine while starting < max && line_left[starting] == line_right[starting] starting += 1 end - if (! "".respond_to?(:force_encoding)) && starting < line_left.size - while line_left[starting].ord.between?(128, 191) && starting > 0 - starting -= 1 - end - end ending = -1 while ending >= -(max - starting) && (line_left[ending] == line_right[ending]) ending -= 1 end - if (! "".respond_to?(:force_encoding)) && ending > (-1 * line_left.size) - while line_left[ending].ord.between?(128, 255) && ending < -1 - if line_left[ending].ord.between?(128, 191) - if line_left[ending + 1].ord.between?(128, 191) - ending += 1 - else - break - end - else - ending += 1 - end - end - end unless starting == 0 && ending == -1 [starting, ending] end @@ -279,7 +261,7 @@ module Redmine def line_to_html(line, offsets) html = line_to_html_raw(line, offsets) - html.force_encoding('UTF-8') if html.respond_to?(:force_encoding) + html.force_encoding('UTF-8') html end diff --git a/lib/tasks/ci.rake b/lib/tasks/ci.rake index 41a334c5e..857cc232d 100644 --- a/lib/tasks/ci.rake +++ b/lib/tasks/ci.rake @@ -33,7 +33,7 @@ namespace :ci do else Rake::Task["test"].invoke end - # Rake::Task["test:ui"].invoke if RUBY_VERSION >= '1.9.3' + # Rake::Task["test:ui"].invoke end desc "Finish the build" @@ -52,7 +52,7 @@ file 'config/database.yml' do case database when 'mysql' - dev_conf = {'adapter' => (RUBY_VERSION >= '1.9' ? 'mysql2' : 'mysql'), + dev_conf = {'adapter' => 'mysql2', 'database' => dev_db_name, 'host' => 'localhost', 'encoding' => 'utf8'} if ENV['RUN_ON_NOT_OFFICIAL'] diff --git a/lib/tasks/locales.rake b/lib/tasks/locales.rake index 6311d6ab1..7d2ecfe80 100644 --- a/lib/tasks/locales.rake +++ b/lib/tasks/locales.rake @@ -68,9 +68,6 @@ namespace :locales do desc <<-END_DESC Removes a translation string from all locale file (only works for top-level childless non-multiline keys, probably doesn\'t work on windows). -This task does not work on Ruby 1.8.6. -You need to use Ruby 1.8.7 or later. - Options: key=key_1,key_2 Comma-separated list of keys to delete skip=en,de Comma-separated list of locale files to ignore (filename without extension) diff --git a/lib/tasks/migrate_from_mantis.rake b/lib/tasks/migrate_from_mantis.rake index 2d5f66f81..1040dbb0a 100644 --- a/lib/tasks/migrate_from_mantis.rake +++ b/lib/tasks/migrate_from_mantis.rake @@ -18,7 +18,6 @@ desc 'Mantis migration script' require 'active_record' -require 'iconv' if RUBY_VERSION < '1.9' require 'pp' namespace :redmine do @@ -452,12 +451,7 @@ task :migrate_from_mantis => :environment do end def self.encode(text) - if RUBY_VERSION < '1.9' - @ic ||= Iconv.new('UTF-8', @charset) - @ic.iconv text - else - text.to_s.force_encoding(@charset).encode('UTF-8') - end + text.to_s.force_encoding(@charset).encode('UTF-8') end end diff --git a/lib/tasks/migrate_from_trac.rake b/lib/tasks/migrate_from_trac.rake index 0d1af9abc..d1a3873f5 100644 --- a/lib/tasks/migrate_from_trac.rake +++ b/lib/tasks/migrate_from_trac.rake @@ -16,7 +16,6 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. require 'active_record' -require 'iconv' if RUBY_VERSION < '1.9' require 'pp' namespace :redmine do @@ -155,7 +154,7 @@ namespace :redmine do attachment_type = read_attribute(:type) #replace exotic characters with their hex representation to avoid invalid filenames trac_file = filename.gsub( /[^a-zA-Z0-9\-_\.!~*']/n ) do |x| - codepoint = RUBY_VERSION < '1.9' ? x[0] : x.codepoints.to_a[0] + codepoint = x.codepoints.to_a[0] sprintf('%%%02x', codepoint) end "#{TracMigrate.trac_attachments_directory}/#{attachment_type}/#{id}/#{trac_file}" @@ -715,12 +714,7 @@ namespace :redmine do end def self.encode(text) - if RUBY_VERSION < '1.9' - @ic ||= Iconv.new('UTF-8', @charset) - @ic.iconv text - else - text.to_s.force_encoding(@charset).encode('UTF-8') - end + text.to_s.force_encoding(@charset).encode('UTF-8') end end diff --git a/script/about b/script/about index cfec3b406..b830b97a6 100755 --- a/script/about +++ b/script/about @@ -1,6 +1,2 @@ #!/usr/bin/env ruby - -ENV["RAILS_ENV"] ||= "production" -require File.expand_path(File.dirname(__FILE__) + "/../config/environment") -puts -puts Redmine::Info.environment +abort "script/about no longer exists, please use bin/about instead." diff --git a/script/rails b/script/rails index f8da2cffd..241275c2e 100755 --- a/script/rails +++ b/script/rails @@ -1,6 +1,2 @@ #!/usr/bin/env ruby -# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application. - -APP_PATH = File.expand_path('../../config/application', __FILE__) -require File.expand_path('../../config/boot', __FILE__) -require 'rails/commands' +abort "script/rails no longer exists, please use bin/rails instead." diff --git a/test/functional/account_controller_test.rb b/test/functional/account_controller_test.rb index faf7356ea..114684b30 100644 --- a/test/functional/account_controller_test.rb +++ b/test/functional/account_controller_test.rb @@ -72,8 +72,8 @@ class AccountControllerTest < ActionController::TestCase end def test_login_with_suburi_should_redirect_to_back_url_param - @relative_url_root = ApplicationController.relative_url_root - ApplicationController.relative_url_root = '/redmine' + @relative_url_root = Redmine::Utils.relative_url_root + Redmine::Utils.relative_url_root = '/redmine' back_urls = [ 'http://test.host/redmine/issues/show/1', @@ -84,7 +84,7 @@ class AccountControllerTest < ActionController::TestCase assert_redirected_to back_url end ensure - ApplicationController.relative_url_root = @relative_url_root + Redmine::Utils.relative_url_root = @relative_url_root end def test_login_should_not_redirect_to_another_host @@ -99,8 +99,8 @@ class AccountControllerTest < ActionController::TestCase end def test_login_with_suburi_should_not_redirect_to_another_suburi - @relative_url_root = ApplicationController.relative_url_root - ApplicationController.relative_url_root = '/redmine' + @relative_url_root = Redmine::Utils.relative_url_root + Redmine::Utils.relative_url_root = '/redmine' back_urls = [ 'http://test.host/', @@ -115,7 +115,7 @@ class AccountControllerTest < ActionController::TestCase assert_redirected_to '/my/page' end ensure - ApplicationController.relative_url_root = @relative_url_root + Redmine::Utils.relative_url_root = @relative_url_root end def test_login_with_wrong_password diff --git a/test/functional/activities_controller_test.rb b/test/functional/activities_controller_test.rb index 49d5aff61..06c1624b0 100644 --- a/test/functional/activities_controller_test.rb +++ b/test/functional/activities_controller_test.rb @@ -127,11 +127,13 @@ class ActivitiesControllerTest < ActionController::TestCase end def test_index_atom_feed_with_one_item_type - get :index, :format => 'atom', :show_issues => '1' - assert_response :success - assert_template 'common/feed' - - assert_select 'title', :text => /Issues/ + with_settings :default_language => 'en' do + get :index, :format => 'atom', :show_issues => '1' + assert_response :success + assert_template 'common/feed' + + assert_select 'title', :text => /Issues/ + end end def test_index_should_show_private_notes_with_permission_only diff --git a/test/functional/attachments_controller_test.rb b/test/functional/attachments_controller_test.rb index 018f848d9..4da2f5f66 100644 --- a/test/functional/attachments_controller_test.rb +++ b/test/functional/attachments_controller_test.rb @@ -139,8 +139,7 @@ class AttachmentsControllerTest < ActionController::TestCase assert a.save assert_equal 'japanese-utf-8.txt', a.filename - str_japanese = "\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e" - str_japanese.force_encoding('UTF-8') if str_japanese.respond_to?(:force_encoding) + str_japanese = "\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e".force_encoding('UTF-8') get :show, :id => a.id assert_response :success diff --git a/test/functional/calendars_controller_test.rb b/test/functional/calendars_controller_test.rb index e67d05dfb..01f9a8ce1 100644 --- a/test/functional/calendars_controller_test.rb +++ b/test/functional/calendars_controller_test.rb @@ -48,10 +48,10 @@ class CalendarsControllerTest < ActionController::TestCase end def test_week_number_calculation - Setting.start_of_week = 7 - - get :show, :month => '1', :year => '2010' - assert_response :success + with_settings :start_of_week => 7 do + get :show, :month => '1', :year => '2010' + assert_response :success + end assert_select 'tr' do assert_select 'td.week-number', :text => '53' @@ -65,9 +65,10 @@ class CalendarsControllerTest < ActionController::TestCase assert_select 'td.even', :text => '9' end - Setting.start_of_week = 1 - get :show, :month => '1', :year => '2010' - assert_response :success + with_settings :start_of_week => 1 do + get :show, :month => '1', :year => '2010' + assert_response :success + end assert_select 'tr' do assert_select 'td.week-number', :text => '53' diff --git a/test/functional/context_menus_controller_test.rb b/test/functional/context_menus_controller_test.rb index 6670927cd..3a18ca30a 100644 --- a/test/functional/context_menus_controller_test.rb +++ b/test/functional/context_menus_controller_test.rb @@ -56,12 +56,14 @@ class ContextMenusControllerTest < ActionController::TestCase end def test_context_menu_one_issue_by_anonymous - get :issues, :ids => [1] - assert_response :success - assert_template 'context_menus/issues' - assert_tag :tag => 'a', :content => 'Delete', - :attributes => { :href => '#', - :class => 'icon-del disabled' } + with_settings :default_language => 'en' do + get :issues, :ids => [1] + assert_response :success + assert_template 'context_menus/issues' + assert_tag :tag => 'a', :content => 'Delete', + :attributes => { :href => '#', + :class => 'icon-del disabled' } + end end def test_context_menu_multiple_issues_of_same_project diff --git a/test/functional/custom_fields_controller_test.rb b/test/functional/custom_fields_controller_test.rb index 76579d74a..0d86df204 100644 --- a/test/functional/custom_fields_controller_test.rb +++ b/test/functional/custom_fields_controller_test.rb @@ -112,7 +112,7 @@ class CustomFieldsControllerTest < ActionController::TestCase end def test_new_js - get :new, :type => 'IssueCustomField', :custom_field => {:field_format => 'list'}, :format => 'js' + xhr :get, :new, :type => 'IssueCustomField', :custom_field => {:field_format => 'list'}, :format => 'js' assert_response :success assert_template 'new' assert_equal 'text/javascript', response.content_type diff --git a/test/functional/groups_controller_test.rb b/test/functional/groups_controller_test.rb index 252472ab6..d1a2b6729 100644 --- a/test/functional/groups_controller_test.rb +++ b/test/functional/groups_controller_test.rb @@ -201,7 +201,7 @@ class GroupsControllerTest < ActionController::TestCase end def test_autocomplete_for_user - get :autocomplete_for_user, :id => 10, :q => 'smi', :format => 'js' + xhr :get, :autocomplete_for_user, :id => 10, :q => 'smi', :format => 'js' assert_response :success assert_include 'John Smith', response.body end diff --git a/test/functional/issues_controller_test.rb b/test/functional/issues_controller_test.rb index 44c43e3b2..6b2dd7110 100644 --- a/test/functional/issues_controller_test.rb +++ b/test/functional/issues_controller_test.rb @@ -474,12 +474,8 @@ class IssuesControllerTest < ActionController::TestCase def test_index_csv_big_5 with_settings :default_language => "zh-TW" do - str_utf8 = "\xe4\xb8\x80\xe6\x9c\x88" - str_big5 = "\xa4@\xa4\xeb" - if str_utf8.respond_to?(:force_encoding) - str_utf8.force_encoding('UTF-8') - str_big5.force_encoding('Big5') - end + str_utf8 = "\xe4\xb8\x80\xe6\x9c\x88".force_encoding('UTF-8') + str_big5 = "\xa4@\xa4\xeb".force_encoding('Big5') issue = Issue.generate!(:subject => str_utf8) get :index, :project_id => 1, @@ -488,10 +484,7 @@ class IssuesControllerTest < ActionController::TestCase :format => 'csv' assert_equal 'text/csv; header=present', @response.content_type lines = @response.body.chomp.split("\n") - s1 = "\xaa\xac\xbaA" - if str_utf8.respond_to?(:force_encoding) - s1.force_encoding('Big5') - end + s1 = "\xaa\xac\xbaA".force_encoding('Big5') assert_include s1, lines[0] assert_include str_big5, lines[1] end @@ -499,10 +492,7 @@ class IssuesControllerTest < ActionController::TestCase def test_index_csv_cannot_convert_should_be_replaced_big_5 with_settings :default_language => "zh-TW" do - str_utf8 = "\xe4\xbb\xa5\xe5\x86\x85" - if str_utf8.respond_to?(:force_encoding) - str_utf8.force_encoding('UTF-8') - end + str_utf8 = "\xe4\xbb\xa5\xe5\x86\x85".force_encoding('UTF-8') issue = Issue.generate!(:subject => str_utf8) get :index, :project_id => 1, @@ -513,21 +503,11 @@ class IssuesControllerTest < ActionController::TestCase :set_filter => 1 assert_equal 'text/csv; header=present', @response.content_type lines = @response.body.chomp.split("\n") - s1 = "\xaa\xac\xbaA" # status - if str_utf8.respond_to?(:force_encoding) - s1.force_encoding('Big5') - end + s1 = "\xaa\xac\xbaA".force_encoding('Big5') # status assert lines[0].include?(s1) s2 = lines[1].split(",")[2] - if s1.respond_to?(:force_encoding) - s3 = "\xa5H?" # subject - s3.force_encoding('Big5') - assert_equal s3, s2 - elsif RUBY_PLATFORM == 'java' - assert_equal "??", s2 - else - assert_equal "\xa5H???", s2 - end + s3 = "\xa5H?".force_encoding('Big5') # subject + assert_equal s3, s2 end end @@ -3120,20 +3100,15 @@ class IssuesControllerTest < ActionController::TestCase def test_put_update_with_attachment_that_fails_to_save set_tmp_attachments_directory - # Delete all fixtured journals, a race condition can occur causing the wrong - # journal to get fetched in the next find. - Journal.delete_all - - # Mock out the unsaved attachment - Attachment.any_instance.stubs(:create).returns(Attachment.new) - # anonymous user - put :update, - :id => 1, - :issue => {:notes => ''}, - :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}} - assert_redirected_to :action => 'show', :id => '1' - assert_equal '1 file(s) could not be saved.', flash[:warning] + with_settings :attachment_max_size => 0 do + put :update, + :id => 1, + :issue => {:notes => ''}, + :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}} + assert_redirected_to :action => 'show', :id => '1' + assert_equal '1 file(s) could not be saved.', flash[:warning] + end end def test_put_update_with_no_change @@ -3379,7 +3354,7 @@ class IssuesControllerTest < ActionController::TestCase post :bulk_edit, :ids => [1, 2, 6], :issue => {:project_id => 1} assert_response :success assert_template 'bulk_edit' - assert_equal Project.find(1).shared_versions.open.all.sort, assigns(:versions).sort + assert_equal Project.find(1).shared_versions.open.to_a.sort, assigns(:versions).sort assert_select 'select[name=?]', 'issue[fixed_version_id]' do assert_select 'option', :text => '2.0' diff --git a/test/functional/issues_custom_fields_visibility_test.rb b/test/functional/issues_custom_fields_visibility_test.rb index cf164665a..afa54c933 100644 --- a/test/functional/issues_custom_fields_visibility_test.rb +++ b/test/functional/issues_custom_fields_visibility_test.rb @@ -199,8 +199,8 @@ class IssuesCustomFieldsVisibilityTest < ActionController::TestCase p1 = Project.generate! p2 = Project.generate! user = User.generate! - User.add_to_project(user, p1, Role.where(:id => [1, 3]).all) - User.add_to_project(user, p2, Role.where(:id => 3).all) + User.add_to_project(user, p1, Role.where(:id => [1, 3]).to_a) + User.add_to_project(user, p2, Role.where(:id => 3).to_a) Issue.generate!(:project => p1, :tracker_id => 1, :custom_field_values => {@field2.id => 'ValueA'}) Issue.generate!(:project => p2, :tracker_id => 1, :custom_field_values => {@field2.id => 'ValueB'}) Issue.generate!(:project => p1, :tracker_id => 1, :custom_field_values => {@field2.id => 'ValueC'}) diff --git a/test/functional/members_controller_test.rb b/test/functional/members_controller_test.rb index 4710916ad..a1ab6f93a 100644 --- a/test/functional/members_controller_test.rb +++ b/test/functional/members_controller_test.rb @@ -104,7 +104,7 @@ class MembersControllerTest < ActionController::TestCase end def test_autocomplete - get :autocomplete, :project_id => 1, :q => 'mis', :format => 'js' + xhr :get, :autocomplete, :project_id => 1, :q => 'mis', :format => 'js' assert_response :success assert_include 'User Misc', response.body end diff --git a/test/functional/messages_controller_test.rb b/test/functional/messages_controller_test.rb index 075bab96f..8b15d517a 100644 --- a/test/functional/messages_controller_test.rb +++ b/test/functional/messages_controller_test.rb @@ -59,8 +59,8 @@ class MessagesControllerTest < ActionController::TestCase assert_template 'show' replies = assigns(:replies) assert_not_nil replies - assert !replies.include?(message.children.order('id').first) - assert replies.include?(message.children.order('id').last) + assert_not_include message.children.reorder('id').first, replies + assert_include message.children.reorder('id').last, replies end def test_show_with_reply_permission diff --git a/test/functional/my_controller_test.rb b/test/functional/my_controller_test.rb index 53c73341a..b9e965491 100644 --- a/test/functional/my_controller_test.rb +++ b/test/functional/my_controller_test.rb @@ -167,7 +167,7 @@ class MyControllerTest < ActionController::TestCase :new_password_confirmation => 'secret1234' assert_response :success assert_template 'password' - assert_error_tag :content => /Password doesn't match confirmation/ + assert_error_tag :content => /Password doesn.*t match confirmation/ # wrong password post :password, :password => 'wrongpassword', diff --git a/test/functional/repositories_bazaar_controller_test.rb b/test/functional/repositories_bazaar_controller_test.rb index 2321f2ec2..5da8549df 100644 --- a/test/functional/repositories_bazaar_controller_test.rb +++ b/test/functional/repositories_bazaar_controller_test.rb @@ -26,7 +26,7 @@ class RepositoriesBazaarControllerTest < ActionController::TestCase REPOSITORY_PATH = Rails.root.join('tmp/test/bazaar_repository').to_s REPOSITORY_PATH_TRUNK = File.join(REPOSITORY_PATH, "trunk") PRJ_ID = 3 - CHAR_1_UTF8_HEX = "\xc3\x9c" + CHAR_1_UTF8_HEX = "\xc3\x9c".dup.force_encoding('UTF-8') def setup User.current = nil @@ -36,10 +36,6 @@ class RepositoriesBazaarControllerTest < ActionController::TestCase :url => REPOSITORY_PATH_TRUNK, :log_encoding => 'UTF-8') assert @repository - @char_1_utf8 = CHAR_1_UTF8_HEX.dup - if @char_1_utf8.respond_to?(:force_encoding) - @char_1_utf8.force_encoding('UTF-8') - end end if File.directory?(REPOSITORY_PATH) @@ -176,31 +172,29 @@ class RepositoriesBazaarControllerTest < ActionController::TestCase end end - if REPOSITORY_PATH.respond_to?(:force_encoding) - def test_annotate_author_non_ascii - log_encoding = nil - if Encoding.locale_charmap == "UTF-8" || - Encoding.locale_charmap == "ISO-8859-1" - log_encoding = Encoding.locale_charmap - end - unless log_encoding.nil? - repository = Repository::Bazaar.create( - :project => @project, - :url => File.join(REPOSITORY_PATH, "author_non_ascii"), - :identifier => 'author_non_ascii', - :log_encoding => log_encoding) - assert repository - get :annotate, :id => PRJ_ID, :repository_id => 'author_non_ascii', - :path => repository_path_hash(['author-non-ascii-test.txt'])[:param] - assert_response :success - assert_template 'annotate' - assert_select "th.line-num", :text => '1' do - assert_select "+ td.revision" do - assert_select "a", :text => '2' - assert_select "+ td.author", :text => "test #{@char_1_utf8}" do - assert_select "+ td", - :text => "author non ASCII test" - end + def test_annotate_author_non_ascii + log_encoding = nil + if Encoding.locale_charmap == "UTF-8" || + Encoding.locale_charmap == "ISO-8859-1" + log_encoding = Encoding.locale_charmap + end + unless log_encoding.nil? + repository = Repository::Bazaar.create( + :project => @project, + :url => File.join(REPOSITORY_PATH, "author_non_ascii"), + :identifier => 'author_non_ascii', + :log_encoding => log_encoding) + assert repository + get :annotate, :id => PRJ_ID, :repository_id => 'author_non_ascii', + :path => repository_path_hash(['author-non-ascii-test.txt'])[:param] + assert_response :success + assert_template 'annotate' + assert_select "th.line-num", :text => '1' do + assert_select "+ td.revision" do + assert_select "a", :text => '2' + assert_select "+ td.author", :text => "test #{CHAR_1_UTF8_HEX}" do + assert_select "+ td", + :text => "author non ASCII test" end end end diff --git a/test/functional/repositories_filesystem_controller_test.rb b/test/functional/repositories_filesystem_controller_test.rb index 0a1f7da36..ee904d8e5 100644 --- a/test/functional/repositories_filesystem_controller_test.rb +++ b/test/functional/repositories_filesystem_controller_test.rb @@ -27,8 +27,7 @@ class RepositoriesFilesystemControllerTest < ActionController::TestCase PRJ_ID = 3 def setup - @ruby19_non_utf8_pass = - (RUBY_VERSION >= '1.9' && Encoding.default_external.to_s != 'UTF-8') + @ruby19_non_utf8_pass = Encoding.default_external.to_s != 'UTF-8' User.current = nil Setting.enabled_scm << 'Filesystem' unless Setting.enabled_scm.include?('Filesystem') @project = Project.find(PRJ_ID) @@ -94,12 +93,11 @@ class RepositoriesFilesystemControllerTest < ActionController::TestCase :attributes => { :class => 'line-num' }, :sibling => { :tag => 'td', :content => /japanese/ } if @ruby19_non_utf8_pass - puts "TODO: show repository file contents test fails in Ruby 1.9 " + - "and Encoding.default_external is not UTF-8. " + + puts "TODO: show repository file contents test fails " + + "when Encoding.default_external is not UTF-8. " + "Current value is '#{Encoding.default_external.to_s}'" else - str_japanese = "\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e" - str_japanese.force_encoding('UTF-8') if str_japanese.respond_to?(:force_encoding) + str_japanese = "\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e".force_encoding('UTF-8') assert_tag :tag => 'th', :content => '3', :attributes => { :class => 'line-num' }, @@ -109,7 +107,7 @@ class RepositoriesFilesystemControllerTest < ActionController::TestCase end def test_show_utf16 - enc = (RUBY_VERSION == "1.9.2" ? 'UTF-16LE' : 'UTF-16') + enc = 'UTF-16' with_settings :repositories_encodings => enc do get :entry, :id => PRJ_ID, :path => repository_path_hash(['japanese', 'utf-16.txt'])[:param] diff --git a/test/functional/repositories_git_controller_test.rb b/test/functional/repositories_git_controller_test.rb index 25467e585..e20adeab5 100644 --- a/test/functional/repositories_git_controller_test.rb +++ b/test/functional/repositories_git_controller_test.rb @@ -26,8 +26,8 @@ class RepositoriesGitControllerTest < ActionController::TestCase REPOSITORY_PATH = Rails.root.join('tmp/test/git_repository').to_s REPOSITORY_PATH.gsub!(/\//, "\\") if Redmine::Platform.mswin? PRJ_ID = 3 - CHAR_1_HEX = "\xc3\x9c" - FELIX_HEX = "Felix Sch\xC3\xA4fer" + CHAR_1_HEX = "\xc3\x9c".force_encoding('UTF-8') + FELIX_HEX = "Felix Sch\xC3\xA4fer".force_encoding('UTF-8') NUM_REV = 28 ## Git, Mercurial and CVS path encodings are binary. @@ -39,8 +39,7 @@ class RepositoriesGitControllerTest < ActionController::TestCase JRUBY_SKIP_STR = "TODO: This test fails in JRuby" def setup - @ruby19_non_utf8_pass = - (RUBY_VERSION >= '1.9' && Encoding.default_external.to_s != 'UTF-8') + @ruby19_non_utf8_pass = Encoding.default_external.to_s != 'UTF-8' User.current = nil @project = Project.find(PRJ_ID) @@ -50,12 +49,6 @@ class RepositoriesGitControllerTest < ActionController::TestCase :path_encoding => 'ISO-8859-1' ) assert @repository - @char_1 = CHAR_1_HEX.dup - @felix_utf8 = FELIX_HEX.dup - if @char_1.respond_to?(:force_encoding) - @char_1.force_encoding('UTF-8') - @felix_utf8.force_encoding('UTF-8') - end end def test_create_and_update @@ -231,7 +224,7 @@ class RepositoriesGitControllerTest < ActionController::TestCase with_settings :repositories_encodings => 'UTF-8,ISO-8859-1' do ['57ca437c', '57ca437c0acbbcb749821fdf3726a1367056d364'].each do |r1| get :entry, :id => PRJ_ID, - :path => repository_path_hash(['latin-1-dir', "test-#{@char_1}.txt"])[:param], + :path => repository_path_hash(['latin-1-dir', "test-#{CHAR_1_HEX}.txt"])[:param], :rev => r1 assert_response :success assert_template 'entry' @@ -239,7 +232,7 @@ class RepositoriesGitControllerTest < ActionController::TestCase :content => '1', :attributes => { :class => 'line-num' }, :sibling => { :tag => 'td', - :content => /test-#{@char_1}.txt/ } + :content => /test-#{CHAR_1_HEX}.txt/ } end end end @@ -419,14 +412,14 @@ class RepositoriesGitControllerTest < ActionController::TestCase :descendant => { :tag => 'th', :attributes => { :class => 'filename' } , - :content => /latin-1-dir\/test-#{@char_1}.txt/ , + :content => /latin-1-dir\/test-#{CHAR_1_HEX}.txt/ , }, :sibling => { :tag => 'tbody', :descendant => { :tag => 'td', :attributes => { :class => /diff_in/ }, - :content => /test-#{@char_1}.txt/ + :content => /test-#{CHAR_1_HEX}.txt/ } } end @@ -498,11 +491,13 @@ class RepositoriesGitControllerTest < ActionController::TestCase end def test_annotate_binary_file - get :annotate, :id => PRJ_ID, - :path => repository_path_hash(['images', 'edit.png'])[:param] - assert_response 500 - assert_tag :tag => 'p', :attributes => { :id => /errorExplanation/ }, - :content => /cannot be annotated/ + with_settings :default_language => 'en' do + get :annotate, :id => PRJ_ID, + :path => repository_path_hash(['images', 'edit.png'])[:param] + assert_response 500 + assert_tag :tag => 'p', :attributes => { :id => /errorExplanation/ }, + :content => /cannot be annotated/ + end end def test_annotate_error_when_too_big @@ -533,14 +528,14 @@ class RepositoriesGitControllerTest < ActionController::TestCase with_settings :repositories_encodings => 'UTF-8,ISO-8859-1' do ['57ca437c', '57ca437c0acbbcb749821fdf3726a1367056d364'].each do |r1| get :annotate, :id => PRJ_ID, - :path => repository_path_hash(['latin-1-dir', "test-#{@char_1}.txt"])[:param], + :path => repository_path_hash(['latin-1-dir', "test-#{CHAR_1_HEX}.txt"])[:param], :rev => r1 assert_select "th.line-num", :text => '1' do assert_select "+ td.revision" do assert_select "a", :text => '57ca437c' assert_select "+ td.author", :text => "jsmith" do assert_select "+ td", - :text => "test-#{@char_1}.txt" + :text => "test-#{CHAR_1_HEX}.txt" end end end @@ -557,7 +552,7 @@ class RepositoriesGitControllerTest < ActionController::TestCase assert_select "th.line-num", :text => '1' do assert_select "+ td.revision" do assert_select "a", :text => '83ca5fd5' - assert_select "+ td.author", :text => @felix_utf8 do + assert_select "+ td.author", :text => FELIX_HEX do assert_select "+ td", :text => "And this is a file with a leading and trailing space..." end @@ -643,8 +638,8 @@ class RepositoriesGitControllerTest < ActionController::TestCase private def puts_ruby19_non_utf8_pass - puts "TODO: This test fails in Ruby 1.9 " + - "and Encoding.default_external is not UTF-8. " + + puts "TODO: This test fails " + + "when Encoding.default_external is not UTF-8. " + "Current value is '#{Encoding.default_external.to_s}'" end else diff --git a/test/functional/repositories_mercurial_controller_test.rb b/test/functional/repositories_mercurial_controller_test.rb index 8eec4f3de..382aa5ccf 100644 --- a/test/functional/repositories_mercurial_controller_test.rb +++ b/test/functional/repositories_mercurial_controller_test.rb @@ -28,8 +28,7 @@ class RepositoriesMercurialControllerTest < ActionController::TestCase PRJ_ID = 3 NUM_REV = 34 - ruby19_non_utf8_pass = - (RUBY_VERSION >= '1.9' && Encoding.default_external.to_s != 'UTF-8') + ruby19_non_utf8_pass = Encoding.default_external.to_s != 'UTF-8' def setup User.current = nil @@ -41,21 +40,15 @@ class RepositoriesMercurialControllerTest < ActionController::TestCase ) assert @repository @diff_c_support = true - @char_1 = CHAR_1_HEX.dup - @tag_char_1 = "tag-#{CHAR_1_HEX}-00" - @branch_char_0 = "branch-#{CHAR_1_HEX}-00" - @branch_char_1 = "branch-#{CHAR_1_HEX}-01" - if @char_1.respond_to?(:force_encoding) - @char_1.force_encoding('UTF-8') - @tag_char_1.force_encoding('UTF-8') - @branch_char_0.force_encoding('UTF-8') - @branch_char_1.force_encoding('UTF-8') - end + @char_1 = CHAR_1_HEX.dup.force_encoding('UTF-8') + @tag_char_1 = "tag-#{CHAR_1_HEX}-00".force_encoding('UTF-8') + @branch_char_0 = "branch-#{CHAR_1_HEX}-00".force_encoding('UTF-8') + @branch_char_1 = "branch-#{CHAR_1_HEX}-01".force_encoding('UTF-8') end if ruby19_non_utf8_pass - puts "TODO: Mercurial functional test fails in Ruby 1.9 " + - "and Encoding.default_external is not UTF-8. " + + puts "TODO: Mercurial functional test fails " + + "when Encoding.default_external is not UTF-8. " + "Current value is '#{Encoding.default_external.to_s}'" def test_fake; assert true end elsif File.directory?(REPOSITORY_PATH) diff --git a/test/functional/roles_controller_test.rb b/test/functional/roles_controller_test.rb index 54509b77c..6e1fc3da5 100644 --- a/test/functional/roles_controller_test.rb +++ b/test/functional/roles_controller_test.rb @@ -31,7 +31,7 @@ class RolesControllerTest < ActionController::TestCase assert_template 'index' assert_not_nil assigns(:roles) - assert_equal Role.order('builtin, position').all, assigns(:roles) + assert_equal Role.order('builtin, position').to_a, assigns(:roles) assert_tag :tag => 'a', :attributes => { :href => '/roles/1/edit' }, :content => 'Manager' @@ -160,7 +160,7 @@ class RolesControllerTest < ActionController::TestCase assert_template 'permissions' assert_not_nil assigns(:roles) - assert_equal Role.order('builtin, position').all, assigns(:roles) + assert_equal Role.order('builtin, position').to_a, assigns(:roles) assert_tag :tag => 'input', :attributes => { :type => 'checkbox', :name => 'permissions[3][]', diff --git a/test/functional/search_controller_test.rb b/test/functional/search_controller_test.rb index 25bd36f15..5b8e1acc4 100644 --- a/test/functional/search_controller_test.rb +++ b/test/functional/search_controller_test.rb @@ -40,7 +40,9 @@ class SearchControllerTest < ActionController::TestCase end def test_search_all_projects - get :index, :q => 'recipe subproject commit', :all_words => '' + with_settings :default_language => 'en' do + get :index, :q => 'recipe subproject commit', :all_words => '' + end assert_response :success assert_template 'index' diff --git a/test/functional/time_entry_reports_controller_test.rb b/test/functional/time_entry_reports_controller_test.rb index bbc4d3c1d..16a477079 100644 --- a/test/functional/time_entry_reports_controller_test.rb +++ b/test/functional/time_entry_reports_controller_test.rb @@ -240,12 +240,8 @@ class TimeEntryReportsControllerTest < ActionController::TestCase def test_csv_big_5 Setting.default_language = "zh-TW" - str_utf8 = "\xe4\xb8\x80\xe6\x9c\x88" - str_big5 = "\xa4@\xa4\xeb" - if str_utf8.respond_to?(:force_encoding) - str_utf8.force_encoding('UTF-8') - str_big5.force_encoding('Big5') - end + str_utf8 = "\xe4\xb8\x80\xe6\x9c\x88".force_encoding('UTF-8') + str_big5 = "\xa4@\xa4\xeb".force_encoding('Big5') user = User.find_by_id(3) user.firstname = str_utf8 user.lastname = "test-lastname" @@ -270,21 +266,14 @@ class TimeEntryReportsControllerTest < ActionController::TestCase assert_equal 'text/csv; header=present', @response.content_type lines = @response.body.chomp.split("\n") # Headers - s1 = "\xa5\xce\xa4\xe1,2011-11-11,\xa4u\xae\xc9\xc1`\xadp" - s2 = "\xa4u\xae\xc9\xc1`\xadp" - if s1.respond_to?(:force_encoding) - s1.force_encoding('Big5') - s2.force_encoding('Big5') - end + s1 = "\xa5\xce\xa4\xe1,2011-11-11,\xa4u\xae\xc9\xc1`\xadp".force_encoding('Big5') + s2 = "\xa4u\xae\xc9\xc1`\xadp".force_encoding('Big5') assert_equal s1, lines.first # Total row assert_equal "#{str_big5} #{user.lastname},7.30,7.30", lines[1] assert_equal "#{s2},7.30,7.30", lines[2] - str_tw = "Traditional Chinese (\xe7\xb9\x81\xe9\xab\x94\xe4\xb8\xad\xe6\x96\x87)" - if str_tw.respond_to?(:force_encoding) - str_tw.force_encoding('UTF-8') - end + str_tw = "Traditional Chinese (\xe7\xb9\x81\xe9\xab\x94\xe4\xb8\xad\xe6\x96\x87)".force_encoding('UTF-8') assert_equal str_tw, l(:general_lang_name) assert_equal 'Big5', l(:general_csv_encoding) assert_equal ',', l(:general_csv_separator) @@ -293,10 +282,7 @@ class TimeEntryReportsControllerTest < ActionController::TestCase def test_csv_cannot_convert_should_be_replaced_big_5 Setting.default_language = "zh-TW" - str_utf8 = "\xe4\xbb\xa5\xe5\x86\x85" - if str_utf8.respond_to?(:force_encoding) - str_utf8.force_encoding('UTF-8') - end + str_utf8 = "\xe4\xbb\xa5\xe5\x86\x85".force_encoding('UTF-8') user = User.find_by_id(3) user.firstname = str_utf8 user.lastname = "test-lastname" @@ -321,21 +307,10 @@ class TimeEntryReportsControllerTest < ActionController::TestCase assert_equal 'text/csv; header=present', @response.content_type lines = @response.body.chomp.split("\n") # Headers - s1 = "\xa5\xce\xa4\xe1,2011-11-11,\xa4u\xae\xc9\xc1`\xadp" - if s1.respond_to?(:force_encoding) - s1.force_encoding('Big5') - end + s1 = "\xa5\xce\xa4\xe1,2011-11-11,\xa4u\xae\xc9\xc1`\xadp".force_encoding('Big5') assert_equal s1, lines.first # Total row - s2 = "" - if s2.respond_to?(:force_encoding) - s2 = "\xa5H?" - s2.force_encoding('Big5') - elsif RUBY_PLATFORM == 'java' - s2 = "??" - else - s2 = "\xa5H???" - end + s2 = "\xa5H?".force_encoding('Big5') assert_equal "#{s2} #{user.lastname},7.30,7.30", lines[1] end @@ -362,21 +337,14 @@ class TimeEntryReportsControllerTest < ActionController::TestCase assert_equal 'text/csv; header=present', @response.content_type lines = @response.body.chomp.split("\n") # Headers - s1 = "Utilisateur;2011-11-11;Temps total" - s2 = "Temps total" - if s1.respond_to?(:force_encoding) - s1.force_encoding('ISO-8859-1') - s2.force_encoding('ISO-8859-1') - end + s1 = "Utilisateur;2011-11-11;Temps total".force_encoding('ISO-8859-1') + s2 = "Temps total".force_encoding('ISO-8859-1') assert_equal s1, lines.first # Total row assert_equal "#{user.firstname} #{user.lastname};7,30;7,30", lines[1] assert_equal "#{s2};7,30;7,30", lines[2] - str_fr = "Fran\xc3\xa7ais" - if str_fr.respond_to?(:force_encoding) - str_fr.force_encoding('UTF-8') - end + str_fr = "Fran\xc3\xa7ais".force_encoding('UTF-8') assert_equal str_fr, l(:general_lang_name) assert_equal 'ISO-8859-1', l(:general_csv_encoding) assert_equal ';', l(:general_csv_separator) diff --git a/test/functional/timelog_controller_test.rb b/test/functional/timelog_controller_test.rb index cc76cba21..72a45f81b 100644 --- a/test/functional/timelog_controller_test.rb +++ b/test/functional/timelog_controller_test.rb @@ -702,16 +702,18 @@ class TimelogControllerTest < ActionController::TestCase end def test_index_csv_all_projects - Setting.date_format = '%m/%d/%Y' - get :index, :format => 'csv' - assert_response :success - assert_equal 'text/csv; header=present', response.content_type + with_settings :date_format => '%m/%d/%Y' do + get :index, :format => 'csv' + assert_response :success + assert_equal 'text/csv; header=present', response.content_type + end end def test_index_csv - Setting.date_format = '%m/%d/%Y' - get :index, :project_id => 1, :format => 'csv' - assert_response :success - assert_equal 'text/csv; header=present', response.content_type + with_settings :date_format => '%m/%d/%Y' do + get :index, :project_id => 1, :format => 'csv' + assert_response :success + assert_equal 'text/csv; header=present', response.content_type + end end end diff --git a/test/functional/timelog_custom_fields_visibility_test.rb b/test/functional/timelog_custom_fields_visibility_test.rb index 8f474c1d6..a5648de78 100644 --- a/test/functional/timelog_custom_fields_visibility_test.rb +++ b/test/functional/timelog_custom_fields_visibility_test.rb @@ -95,8 +95,8 @@ class TimelogCustomFieldsVisibilityTest < ActionController::TestCase p1 = Project.generate! p2 = Project.generate! user = User.generate! - User.add_to_project(user, p1, Role.where(:id => [1, 3]).all) - User.add_to_project(user, p2, Role.where(:id => 3).all) + User.add_to_project(user, p1, Role.where(:id => [1, 3]).to_a) + User.add_to_project(user, p2, Role.where(:id => 3).to_a) TimeEntry.generate!( :issue => Issue.generate!(:project => p1, :tracker_id => 1, :custom_field_values => {@field2.id => 'ValueA'})) @@ -108,9 +108,9 @@ class TimelogCustomFieldsVisibilityTest < ActionController::TestCase :custom_field_values => {@field2.id => 'ValueC'})) @request.session[:user_id] = user.id get :index, :c => ["hours", "issue.cf_#{@field2.id}"] - assert_select 'td', :text => 'ValueA' + assert_select 'td', {:text => 'ValueA'}, "ValueA not found in:\n#{response.body}" assert_select 'td', :text => 'ValueB', :count => 0 - assert_select 'td', :text => 'ValueC' + assert_select 'td', {:text => 'ValueC'}, "ValueC not found in:\n#{response.body}" get :index, :set_filter => '1', "issue.cf_#{@field2.id}" => '*' assert_equal %w(ValueA ValueC), assigns(:entries).map{|i| i.issue.custom_field_value(@field2)}.sort diff --git a/test/functional/welcome_controller_test.rb b/test/functional/welcome_controller_test.rb index 350918359..aa9afaeaf 100644 --- a/test/functional/welcome_controller_test.rb +++ b/test/functional/welcome_controller_test.rb @@ -97,9 +97,7 @@ class WelcomeControllerTest < ActionController::TestCase @request.session[:user_id] = 2 get :index - assert_tag 'script', - :attributes => {:type => "text/javascript"}, - :content => %r{warnLeavingUnsaved} + assert_select 'script', :text => %r{warnLeavingUnsaved} end def test_warn_on_leaving_unsaved_turn_off diff --git a/test/functional/wiki_controller_test.rb b/test/functional/wiki_controller_test.rb index 3e25be08e..41f5dabdb 100644 --- a/test/functional/wiki_controller_test.rb +++ b/test/functional/wiki_controller_test.rb @@ -58,7 +58,9 @@ class WikiControllerTest < ActionController::TestCase end def test_show_old_version - get :show, :project_id => 'ecookbook', :id => 'CookBook_documentation', :version => '2' + with_settings :default_language => 'en' do + get :show, :project_id => 'ecookbook', :id => 'CookBook_documentation', :version => '2' + end assert_response :success assert_template 'show' @@ -89,7 +91,9 @@ class WikiControllerTest < ActionController::TestCase end def test_show_first_version - get :show, :project_id => 'ecookbook', :id => 'CookBook_documentation', :version => '1' + with_settings :default_language => 'en' do + get :show, :project_id => 'ecookbook', :id => 'CookBook_documentation', :version => '1' + end assert_response :success assert_template 'show' diff --git a/test/functional/workflows_controller_test.rb b/test/functional/workflows_controller_test.rb index ea00cbc77..5885c4e20 100644 --- a/test/functional/workflows_controller_test.rb +++ b/test/functional/workflows_controller_test.rb @@ -248,7 +248,7 @@ class WorkflowsControllerTest < ActionController::TestCase get :permissions, :role_id => 1, :tracker_id => 2, :used_statuses_only => '0' assert_response :success - assert_equal IssueStatus.sorted.all, assigns(:statuses) + assert_equal IssueStatus.sorted.to_a, assigns(:statuses) end def test_post_permissions diff --git a/test/integration/account_test.rb b/test/integration/account_test.rb index 2a5579435..63320b72d 100644 --- a/test/integration/account_test.rb +++ b/test/integration/account_test.rb @@ -17,13 +17,7 @@ require File.expand_path('../../test_helper', __FILE__) -begin - require 'mocha/setup' -rescue - # Won't run some tests -end - -class AccountTest < ActionController::IntegrationTest +class AccountTest < ActionDispatch::IntegrationTest fixtures :users, :roles def test_login diff --git a/test/integration/admin_test.rb b/test/integration/admin_test.rb index eebdf1045..3b60f0c95 100644 --- a/test/integration/admin_test.rb +++ b/test/integration/admin_test.rb @@ -17,7 +17,7 @@ require File.expand_path('../../test_helper', __FILE__) -class AdminTest < ActionController::IntegrationTest +class AdminTest < ActionDispatch::IntegrationTest fixtures :projects, :trackers, :issue_statuses, :issues, :enumerations, :users, :issue_categories, :projects_trackers, diff --git a/test/integration/api_test/authentication_test.rb b/test/integration/api_test/authentication_test.rb index 16c589d3e..b8c9e0746 100644 --- a/test/integration/api_test/authentication_test.rb +++ b/test/integration/api_test/authentication_test.rb @@ -41,11 +41,8 @@ class Redmine::ApiTest::AuthenticationTest < Redmine::ApiTest::Base end def test_invalid_utf8_credentials_should_not_trigger_an_error - invalid_utf8 = "\x82" - if invalid_utf8.respond_to?(:force_encoding) - invalid_utf8.force_encoding('UTF-8') - assert !invalid_utf8.valid_encoding? - end + invalid_utf8 = "\x82".force_encoding('UTF-8') + assert !invalid_utf8.valid_encoding? assert_nothing_raised do get '/users/current.xml', {}, credentials(invalid_utf8, "foo") end diff --git a/test/integration/api_test/memberships_test.rb b/test/integration/api_test/memberships_test.rb index 7ad0c5790..2493c797d 100644 --- a/test/integration/api_test/memberships_test.rb +++ b/test/integration/api_test/memberships_test.rb @@ -165,7 +165,7 @@ class Redmine::ApiTest::MembershipsTest < Redmine::ApiTest::Base assert_response :unprocessable_entity assert_equal 'application/xml', @response.content_type - assert_tag 'errors', :child => {:tag => 'error', :content => /member_roles is invalid/} + assert_tag 'errors', :child => {:tag => 'error', :content => /role can't be empty/i} end test "DELETE /memberships/:id.xml should destroy the membership" do diff --git a/test/integration/api_test/projects_test.rb b/test/integration/api_test/projects_test.rb index 28b8b9452..a345f5822 100644 --- a/test/integration/api_test/projects_test.rb +++ b/test/integration/api_test/projects_test.rb @@ -195,12 +195,12 @@ class Redmine::ApiTest::ProjectsTest < Redmine::ApiTest::Base end test "POST /projects.xml with valid parameters should create the project" do - Setting.default_projects_modules = ['issue_tracking', 'repository'] - - assert_difference('Project.count') do - post '/projects.xml', - {:project => {:name => 'API test', :identifier => 'api-test'}}, - credentials('admin') + with_settings :default_projects_modules => ['issue_tracking', 'repository'] do + assert_difference('Project.count') do + post '/projects.xml', + {:project => {:name => 'API test', :identifier => 'api-test'}}, + credentials('admin') + end end project = Project.order('id DESC').first diff --git a/test/integration/application_test.rb b/test/integration/application_test.rb index 6b5419d90..ced1783e5 100644 --- a/test/integration/application_test.rb +++ b/test/integration/application_test.rb @@ -17,7 +17,7 @@ require File.expand_path('../../test_helper', __FILE__) -class ApplicationTest < ActionController::IntegrationTest +class ApplicationTest < ActionDispatch::IntegrationTest include Redmine::I18n fixtures :projects, :trackers, :issue_statuses, :issues, diff --git a/test/integration/attachments_test.rb b/test/integration/attachments_test.rb index 1a2b92da7..69d42d48a 100644 --- a/test/integration/attachments_test.rb +++ b/test/integration/attachments_test.rb @@ -17,7 +17,7 @@ require File.expand_path('../../test_helper', __FILE__) -class AttachmentsTest < ActionController::IntegrationTest +class AttachmentsTest < ActionDispatch::IntegrationTest fixtures :projects, :enabled_modules, :users, :roles, :members, :member_roles, :trackers, :projects_trackers, diff --git a/test/integration/feeds_test.rb b/test/integration/feeds_test.rb index 0a5e369fb..160174f68 100644 --- a/test/integration/feeds_test.rb +++ b/test/integration/feeds_test.rb @@ -17,7 +17,7 @@ require File.expand_path('../../test_helper', __FILE__) -class FeedsTest < ActionController::IntegrationTest +class FeedsTest < ActionDispatch::IntegrationTest fixtures :projects, :trackers, :issue_statuses, :issues, :enumerations, :users, :issue_categories, :projects_trackers, :enabled_modules, diff --git a/test/integration/issues_test.rb b/test/integration/issues_test.rb index 21faaa93f..1e7efde7a 100644 --- a/test/integration/issues_test.rb +++ b/test/integration/issues_test.rb @@ -17,7 +17,7 @@ require File.expand_path('../../test_helper', __FILE__) -class IssuesTest < ActionController::IntegrationTest +class IssuesTest < ActionDispatch::IntegrationTest fixtures :projects, :users, :roles, @@ -132,27 +132,27 @@ class IssuesTest < ActionController::IntegrationTest end def test_pagination_links_on_index - Setting.per_page_options = '2' - get '/projects/ecookbook/issues' - - assert_tag :a, :content => '2', - :attributes => { :href => '/projects/ecookbook/issues?page=2' } + with_settings :per_page_options => '2' do + get '/projects/ecookbook/issues' + assert_tag :a, :content => '2', + :attributes => { :href => '/projects/ecookbook/issues?page=2' } + end end def test_pagination_links_on_index_without_project_id_in_url - Setting.per_page_options = '2' - get '/issues', :project_id => 'ecookbook' - - assert_tag :a, :content => '2', - :attributes => { :href => '/projects/ecookbook/issues?page=2' } - + with_settings :per_page_options => '2' do + get '/issues', :project_id => 'ecookbook' + + assert_tag :a, :content => '2', + :attributes => { :href => '/projects/ecookbook/issues?page=2' } + end end def test_issue_with_user_custom_field @field = IssueCustomField.create!(:name => 'Tester', :field_format => 'user', :is_for_all => true, :trackers => Tracker.all) Role.anonymous.add_permission! :add_issues, :edit_issues - users = Project.find(1).users + users = Project.find(1).users.uniq.sort tester = users.first # Issue form @@ -205,8 +205,8 @@ class IssuesTest < ActionController::IntegrationTest :issue => { :custom_field_values => {@field.id.to_s => new_tester.id.to_s} } + assert_redirected_to "/issues/#{issue.id}" end - assert_response 302 # Issue view follow_redirect! diff --git a/test/integration/layout_test.rb b/test/integration/layout_test.rb index b2e85cdd1..0e6fa24e8 100644 --- a/test/integration/layout_test.rb +++ b/test/integration/layout_test.rb @@ -17,7 +17,7 @@ require File.expand_path('../../test_helper', __FILE__) -class LayoutTest < ActionController::IntegrationTest +class LayoutTest < ActionDispatch::IntegrationTest fixtures :projects, :trackers, :issue_statuses, :issues, :enumerations, :users, :issue_categories, :projects_trackers, diff --git a/test/integration/lib/redmine/hook_test.rb b/test/integration/lib/redmine/hook_test.rb index d6d581402..2746fb5e3 100644 --- a/test/integration/lib/redmine/hook_test.rb +++ b/test/integration/lib/redmine/hook_test.rb @@ -17,7 +17,7 @@ require File.expand_path('../../../../test_helper', __FILE__) -class HookTest < ActionController::IntegrationTest +class HookTest < ActionDispatch::IntegrationTest fixtures :users, :roles, :projects, :members, :member_roles # Hooks that are manually registered later @@ -34,6 +34,8 @@ class HookTest < ActionController::IntegrationTest end end + Redmine::Hook.clear_listeners + class ContentForInsideHook < Redmine::Hook::ViewListener render_on :view_welcome_index_left, :inline => <<-VIEW <% content_for :header_tags do %> diff --git a/test/integration/lib/redmine/menu_manager_test.rb b/test/integration/lib/redmine/menu_manager_test.rb index 1699a2ac1..5d3826a23 100644 --- a/test/integration/lib/redmine/menu_manager_test.rb +++ b/test/integration/lib/redmine/menu_manager_test.rb @@ -17,7 +17,7 @@ require File.expand_path('../../../../test_helper', __FILE__) -class MenuManagerTest < ActionController::IntegrationTest +class MenuManagerTest < ActionDispatch::IntegrationTest include Redmine::I18n fixtures :projects, :trackers, :issue_statuses, :issues, diff --git a/test/integration/lib/redmine/themes_test.rb b/test/integration/lib/redmine/themes_test.rb index 32c77922e..f0d422c58 100644 --- a/test/integration/lib/redmine/themes_test.rb +++ b/test/integration/lib/redmine/themes_test.rb @@ -17,7 +17,7 @@ require File.expand_path('../../../../test_helper', __FILE__) -class ThemesTest < ActionController::IntegrationTest +class ThemesTest < ActionDispatch::IntegrationTest def setup @theme = Redmine::Themes.themes.last diff --git a/test/integration/projects_test.rb b/test/integration/projects_test.rb index 06499a4b8..fcbf71dae 100644 --- a/test/integration/projects_test.rb +++ b/test/integration/projects_test.rb @@ -17,7 +17,7 @@ require File.expand_path('../../test_helper', __FILE__) -class ProjectsTest < ActionController::IntegrationTest +class ProjectsTest < ActionDispatch::IntegrationTest fixtures :projects, :users, :members, :enabled_modules def test_archive_project diff --git a/test/integration/repositories_git_test.rb b/test/integration/repositories_git_test.rb index 18f3b7e62..14c7d087f 100644 --- a/test/integration/repositories_git_test.rb +++ b/test/integration/repositories_git_test.rb @@ -17,7 +17,7 @@ require File.expand_path('../../test_helper', __FILE__) -class RepositoriesGitTest < ActionController::IntegrationTest +class RepositoriesGitTest < ActionDispatch::IntegrationTest fixtures :projects, :users, :roles, :members, :member_roles, :repositories, :enabled_modules diff --git a/test/integration/routing/account_test.rb b/test/integration/routing/account_test.rb index 7f6a9c981..c6d331ec0 100644 --- a/test/integration/routing/account_test.rb +++ b/test/integration/routing/account_test.rb @@ -17,7 +17,7 @@ require File.expand_path('../../../test_helper', __FILE__) -class RoutingAccountTest < ActionController::IntegrationTest +class RoutingAccountTest < ActionDispatch::IntegrationTest def test_account ["get", "post"].each do |method| assert_routing( diff --git a/test/integration/routing/activities_test.rb b/test/integration/routing/activities_test.rb index 4cab5fbcb..d5b543f40 100644 --- a/test/integration/routing/activities_test.rb +++ b/test/integration/routing/activities_test.rb @@ -17,7 +17,7 @@ require File.expand_path('../../../test_helper', __FILE__) -class RoutingActivitiesTest < ActionController::IntegrationTest +class RoutingActivitiesTest < ActionDispatch::IntegrationTest def test_activities assert_routing( { :method => 'get', :path => "/activity" }, diff --git a/test/integration/routing/admin_test.rb b/test/integration/routing/admin_test.rb index 6e9f90f8c..553ebd6b6 100644 --- a/test/integration/routing/admin_test.rb +++ b/test/integration/routing/admin_test.rb @@ -17,7 +17,7 @@ require File.expand_path('../../../test_helper', __FILE__) -class RoutingAdminTest < ActionController::IntegrationTest +class RoutingAdminTest < ActionDispatch::IntegrationTest def test_administration_panel assert_routing( { :method => 'get', :path => "/admin" }, diff --git a/test/integration/routing/attachments_test.rb b/test/integration/routing/attachments_test.rb index 1d7aabe26..2d5f03241 100644 --- a/test/integration/routing/attachments_test.rb +++ b/test/integration/routing/attachments_test.rb @@ -17,7 +17,7 @@ require File.expand_path('../../../test_helper', __FILE__) -class RoutingAttachmentsTest < ActionController::IntegrationTest +class RoutingAttachmentsTest < ActionDispatch::IntegrationTest def test_attachments assert_routing( { :method => 'get', :path => "/attachments/1" }, diff --git a/test/integration/routing/auth_sources_test.rb b/test/integration/routing/auth_sources_test.rb index 8b73f1f97..1a9605018 100644 --- a/test/integration/routing/auth_sources_test.rb +++ b/test/integration/routing/auth_sources_test.rb @@ -17,7 +17,7 @@ require File.expand_path('../../../test_helper', __FILE__) -class RoutingAuthSourcesTest < ActionController::IntegrationTest +class RoutingAuthSourcesTest < ActionDispatch::IntegrationTest def test_auth_sources assert_routing( { :method => 'get', :path => "/auth_sources" }, diff --git a/test/integration/routing/auto_completes_test.rb b/test/integration/routing/auto_completes_test.rb index c767fcf1c..4b717fc69 100644 --- a/test/integration/routing/auto_completes_test.rb +++ b/test/integration/routing/auto_completes_test.rb @@ -17,7 +17,7 @@ require File.expand_path('../../../test_helper', __FILE__) -class RoutingAutoCompletesTest < ActionController::IntegrationTest +class RoutingAutoCompletesTest < ActionDispatch::IntegrationTest def test_auto_completes assert_routing( { :method => 'get', :path => "/issues/auto_complete" }, diff --git a/test/integration/routing/boards_test.rb b/test/integration/routing/boards_test.rb index d730f3764..6551181c5 100644 --- a/test/integration/routing/boards_test.rb +++ b/test/integration/routing/boards_test.rb @@ -17,7 +17,7 @@ require File.expand_path('../../../test_helper', __FILE__) -class RoutingBoardsTest < ActionController::IntegrationTest +class RoutingBoardsTest < ActionDispatch::IntegrationTest def test_boards assert_routing( { :method => 'get', :path => "/projects/world_domination/boards" }, diff --git a/test/integration/routing/calendars_test.rb b/test/integration/routing/calendars_test.rb index ddb384c3d..9e8dfd15b 100644 --- a/test/integration/routing/calendars_test.rb +++ b/test/integration/routing/calendars_test.rb @@ -17,7 +17,7 @@ require File.expand_path('../../../test_helper', __FILE__) -class RoutingCalendarsTest < ActionController::IntegrationTest +class RoutingCalendarsTest < ActionDispatch::IntegrationTest def test_calendars assert_routing( { :method => 'get', :path => "/issues/calendar" }, diff --git a/test/integration/routing/comments_test.rb b/test/integration/routing/comments_test.rb index 94e33c79c..cd5e259ac 100644 --- a/test/integration/routing/comments_test.rb +++ b/test/integration/routing/comments_test.rb @@ -17,7 +17,7 @@ require File.expand_path('../../../test_helper', __FILE__) -class RoutingCommentsTest < ActionController::IntegrationTest +class RoutingCommentsTest < ActionDispatch::IntegrationTest def test_comments assert_routing( { :method => 'post', :path => "/news/567/comments" }, diff --git a/test/integration/routing/context_menus_test.rb b/test/integration/routing/context_menus_test.rb index 1d4be08fa..caee1ca25 100644 --- a/test/integration/routing/context_menus_test.rb +++ b/test/integration/routing/context_menus_test.rb @@ -17,7 +17,7 @@ require File.expand_path('../../../test_helper', __FILE__) -class RoutingContextMenusTest < ActionController::IntegrationTest +class RoutingContextMenusTest < ActionDispatch::IntegrationTest def test_context_menus_time_entries ["get", "post"].each do |method| assert_routing( diff --git a/test/integration/routing/custom_fields_test.rb b/test/integration/routing/custom_fields_test.rb index c1901d826..6649ecf01 100644 --- a/test/integration/routing/custom_fields_test.rb +++ b/test/integration/routing/custom_fields_test.rb @@ -17,7 +17,7 @@ require File.expand_path('../../../test_helper', __FILE__) -class RoutingCustomFieldsTest < ActionController::IntegrationTest +class RoutingCustomFieldsTest < ActionDispatch::IntegrationTest def test_custom_fields assert_routing( { :method => 'get', :path => "/custom_fields" }, diff --git a/test/integration/routing/documents_test.rb b/test/integration/routing/documents_test.rb index 285f64f59..5efbeb10e 100644 --- a/test/integration/routing/documents_test.rb +++ b/test/integration/routing/documents_test.rb @@ -17,7 +17,7 @@ require File.expand_path('../../../test_helper', __FILE__) -class RoutingDocumentsTest < ActionController::IntegrationTest +class RoutingDocumentsTest < ActionDispatch::IntegrationTest def test_documents_scoped_under_project assert_routing( { :method => 'get', :path => "/projects/567/documents" }, diff --git a/test/integration/routing/enumerations_test.rb b/test/integration/routing/enumerations_test.rb index 9b0676494..8b577e159 100644 --- a/test/integration/routing/enumerations_test.rb +++ b/test/integration/routing/enumerations_test.rb @@ -17,7 +17,7 @@ require File.expand_path('../../../test_helper', __FILE__) -class RoutingEnumerationsTest < ActionController::IntegrationTest +class RoutingEnumerationsTest < ActionDispatch::IntegrationTest def test_enumerations assert_routing( { :method => 'get', :path => "/enumerations" }, diff --git a/test/integration/routing/files_test.rb b/test/integration/routing/files_test.rb index 9f5c8de33..ea6a5aae0 100644 --- a/test/integration/routing/files_test.rb +++ b/test/integration/routing/files_test.rb @@ -17,7 +17,7 @@ require File.expand_path('../../../test_helper', __FILE__) -class RoutingFilesTest < ActionController::IntegrationTest +class RoutingFilesTest < ActionDispatch::IntegrationTest def test_files assert_routing( { :method => 'get', :path => "/projects/33/files" }, diff --git a/test/integration/routing/gantts_test.rb b/test/integration/routing/gantts_test.rb index e9448edd9..c2c626c0e 100644 --- a/test/integration/routing/gantts_test.rb +++ b/test/integration/routing/gantts_test.rb @@ -17,7 +17,7 @@ require File.expand_path('../../../test_helper', __FILE__) -class RoutingGanttsTest < ActionController::IntegrationTest +class RoutingGanttsTest < ActionDispatch::IntegrationTest def test_gantts assert_routing( { :method => 'get', :path => "/issues/gantt" }, diff --git a/test/integration/routing/groups_test.rb b/test/integration/routing/groups_test.rb index cef388789..c89d9c9ae 100644 --- a/test/integration/routing/groups_test.rb +++ b/test/integration/routing/groups_test.rb @@ -17,7 +17,7 @@ require File.expand_path('../../../test_helper', __FILE__) -class RoutingGroupsTest < ActionController::IntegrationTest +class RoutingGroupsTest < ActionDispatch::IntegrationTest def test_groups_resources assert_routing( { :method => 'get', :path => "/groups" }, diff --git a/test/integration/routing/issue_categories_test.rb b/test/integration/routing/issue_categories_test.rb index 537847be9..10f23bae9 100644 --- a/test/integration/routing/issue_categories_test.rb +++ b/test/integration/routing/issue_categories_test.rb @@ -17,7 +17,7 @@ require File.expand_path('../../../test_helper', __FILE__) -class RoutingIssueCategoriesTest < ActionController::IntegrationTest +class RoutingIssueCategoriesTest < ActionDispatch::IntegrationTest def test_issue_categories_scoped_under_project assert_routing( { :method => 'get', :path => "/projects/foo/issue_categories" }, diff --git a/test/integration/routing/issue_relations_test.rb b/test/integration/routing/issue_relations_test.rb index 0588c3530..a9bcbf601 100644 --- a/test/integration/routing/issue_relations_test.rb +++ b/test/integration/routing/issue_relations_test.rb @@ -17,7 +17,7 @@ require File.expand_path('../../../test_helper', __FILE__) -class RoutingIssueRelationsTest < ActionController::IntegrationTest +class RoutingIssueRelationsTest < ActionDispatch::IntegrationTest def test_issue_relations assert_routing( { :method => 'get', :path => "/issues/1/relations" }, diff --git a/test/integration/routing/issue_statuses_test.rb b/test/integration/routing/issue_statuses_test.rb index f03b9668f..550fe9379 100644 --- a/test/integration/routing/issue_statuses_test.rb +++ b/test/integration/routing/issue_statuses_test.rb @@ -17,7 +17,7 @@ require File.expand_path('../../../test_helper', __FILE__) -class RoutingIssueStatusesTest < ActionController::IntegrationTest +class RoutingIssueStatusesTest < ActionDispatch::IntegrationTest def test_issue_statuses assert_routing( { :method => 'get', :path => "/issue_statuses" }, diff --git a/test/integration/routing/issues_test.rb b/test/integration/routing/issues_test.rb index 0c7328a99..0dc3c163f 100644 --- a/test/integration/routing/issues_test.rb +++ b/test/integration/routing/issues_test.rb @@ -17,7 +17,7 @@ require File.expand_path('../../../test_helper', __FILE__) -class RoutingIssuesTest < ActionController::IntegrationTest +class RoutingIssuesTest < ActionDispatch::IntegrationTest def test_issues_rest_actions assert_routing( { :method => 'get', :path => "/issues" }, diff --git a/test/integration/routing/journals_test.rb b/test/integration/routing/journals_test.rb index 0731163ca..390e77425 100644 --- a/test/integration/routing/journals_test.rb +++ b/test/integration/routing/journals_test.rb @@ -17,7 +17,7 @@ require File.expand_path('../../../test_helper', __FILE__) -class RoutingJournalsTest < ActionController::IntegrationTest +class RoutingJournalsTest < ActionDispatch::IntegrationTest def test_journals assert_routing( { :method => 'post', :path => "/issues/1/quoted" }, diff --git a/test/integration/routing/mail_handler_test.rb b/test/integration/routing/mail_handler_test.rb index 8ff55b189..8abb5369a 100644 --- a/test/integration/routing/mail_handler_test.rb +++ b/test/integration/routing/mail_handler_test.rb @@ -17,7 +17,7 @@ require File.expand_path('../../../test_helper', __FILE__) -class RoutingMailHandlerTest < ActionController::IntegrationTest +class RoutingMailHandlerTest < ActionDispatch::IntegrationTest def test_mail_handler assert_routing( { :method => "post", :path => "/mail_handler" }, diff --git a/test/integration/routing/members_test.rb b/test/integration/routing/members_test.rb index e249af7a3..20de5662b 100644 --- a/test/integration/routing/members_test.rb +++ b/test/integration/routing/members_test.rb @@ -17,7 +17,7 @@ require File.expand_path('../../../test_helper', __FILE__) -class RoutingMembersTest < ActionController::IntegrationTest +class RoutingMembersTest < ActionDispatch::IntegrationTest def test_members assert_routing( { :method => 'get', :path => "/projects/5234/memberships.xml" }, diff --git a/test/integration/routing/messages_test.rb b/test/integration/routing/messages_test.rb index a6b84886b..696bc86a6 100644 --- a/test/integration/routing/messages_test.rb +++ b/test/integration/routing/messages_test.rb @@ -17,7 +17,7 @@ require File.expand_path('../../../test_helper', __FILE__) -class RoutingMessagesTest < ActionController::IntegrationTest +class RoutingMessagesTest < ActionDispatch::IntegrationTest def test_messages assert_routing( { :method => 'get', :path => "/boards/22/topics/2" }, diff --git a/test/integration/routing/my_test.rb b/test/integration/routing/my_test.rb index 230babcdd..0f5f3e24b 100644 --- a/test/integration/routing/my_test.rb +++ b/test/integration/routing/my_test.rb @@ -17,7 +17,7 @@ require File.expand_path('../../../test_helper', __FILE__) -class RoutingMyTest < ActionController::IntegrationTest +class RoutingMyTest < ActionDispatch::IntegrationTest def test_my ["get", "post"].each do |method| assert_routing( diff --git a/test/integration/routing/news_test.rb b/test/integration/routing/news_test.rb index a5843d50b..a1ee7b12b 100644 --- a/test/integration/routing/news_test.rb +++ b/test/integration/routing/news_test.rb @@ -17,7 +17,7 @@ require File.expand_path('../../../test_helper', __FILE__) -class RoutingNewsTest < ActionController::IntegrationTest +class RoutingNewsTest < ActionDispatch::IntegrationTest def test_news_index assert_routing( { :method => 'get', :path => "/news" }, diff --git a/test/integration/routing/previews_test.rb b/test/integration/routing/previews_test.rb index f0f4e5279..fcdcfe5bd 100644 --- a/test/integration/routing/previews_test.rb +++ b/test/integration/routing/previews_test.rb @@ -17,7 +17,7 @@ require File.expand_path('../../../test_helper', __FILE__) -class RoutingPreviewsTest < ActionController::IntegrationTest +class RoutingPreviewsTest < ActionDispatch::IntegrationTest def test_previews ["get", "post", "put"].each do |method| assert_routing( diff --git a/test/integration/routing/project_enumerations_test.rb b/test/integration/routing/project_enumerations_test.rb index 4065d0b10..3eda2c481 100644 --- a/test/integration/routing/project_enumerations_test.rb +++ b/test/integration/routing/project_enumerations_test.rb @@ -17,7 +17,7 @@ require File.expand_path('../../../test_helper', __FILE__) -class RoutingProjectEnumerationsTest < ActionController::IntegrationTest +class RoutingProjectEnumerationsTest < ActionDispatch::IntegrationTest def test_project_enumerations assert_routing( { :method => 'put', :path => "/projects/64/enumerations" }, diff --git a/test/integration/routing/projects_test.rb b/test/integration/routing/projects_test.rb index eb3319385..392b871d1 100644 --- a/test/integration/routing/projects_test.rb +++ b/test/integration/routing/projects_test.rb @@ -17,7 +17,7 @@ require File.expand_path('../../../test_helper', __FILE__) -class RoutingProjectsTest < ActionController::IntegrationTest +class RoutingProjectsTest < ActionDispatch::IntegrationTest def test_projects assert_routing( { :method => 'get', :path => "/projects" }, diff --git a/test/integration/routing/queries_test.rb b/test/integration/routing/queries_test.rb index f7265a8b9..ac50fbca7 100644 --- a/test/integration/routing/queries_test.rb +++ b/test/integration/routing/queries_test.rb @@ -17,7 +17,7 @@ require File.expand_path('../../../test_helper', __FILE__) -class RoutingQueriesTest < ActionController::IntegrationTest +class RoutingQueriesTest < ActionDispatch::IntegrationTest def test_queries assert_routing( { :method => 'get', :path => "/queries.xml" }, diff --git a/test/integration/routing/reports_test.rb b/test/integration/routing/reports_test.rb index db8a865c7..2483682f4 100644 --- a/test/integration/routing/reports_test.rb +++ b/test/integration/routing/reports_test.rb @@ -17,7 +17,7 @@ require File.expand_path('../../../test_helper', __FILE__) -class RoutingReportsTest < ActionController::IntegrationTest +class RoutingReportsTest < ActionDispatch::IntegrationTest def test_reports assert_routing( { :method => 'get', :path => "/projects/567/issues/report" }, diff --git a/test/integration/routing/repositories_test.rb b/test/integration/routing/repositories_test.rb index c5c6ee24f..0e46cb95c 100644 --- a/test/integration/routing/repositories_test.rb +++ b/test/integration/routing/repositories_test.rb @@ -17,7 +17,7 @@ require File.expand_path('../../../test_helper', __FILE__) -class RoutingRepositoriesTest < ActionController::IntegrationTest +class RoutingRepositoriesTest < ActionDispatch::IntegrationTest def setup @path_hash = repository_path_hash(%w[path to file.c]) assert_equal "path/to/file.c", @path_hash[:path] diff --git a/test/integration/routing/roles_test.rb b/test/integration/routing/roles_test.rb index 962edcb92..5541984f3 100644 --- a/test/integration/routing/roles_test.rb +++ b/test/integration/routing/roles_test.rb @@ -17,7 +17,7 @@ require File.expand_path('../../../test_helper', __FILE__) -class RoutingRolesTest < ActionController::IntegrationTest +class RoutingRolesTest < ActionDispatch::IntegrationTest def test_roles assert_routing( { :method => 'get', :path => "/roles" }, diff --git a/test/integration/routing/search_test.rb b/test/integration/routing/search_test.rb index 96c2ac2d8..6ea40fd73 100644 --- a/test/integration/routing/search_test.rb +++ b/test/integration/routing/search_test.rb @@ -17,7 +17,7 @@ require File.expand_path('../../../test_helper', __FILE__) -class RoutingSearchTest < ActionController::IntegrationTest +class RoutingSearchTest < ActionDispatch::IntegrationTest def test_search assert_routing( { :method => 'get', :path => "/search" }, diff --git a/test/integration/routing/settings_test.rb b/test/integration/routing/settings_test.rb index c36989c23..4cc986d27 100644 --- a/test/integration/routing/settings_test.rb +++ b/test/integration/routing/settings_test.rb @@ -17,7 +17,7 @@ require File.expand_path('../../../test_helper', __FILE__) -class RoutingSettingsTest < ActionController::IntegrationTest +class RoutingSettingsTest < ActionDispatch::IntegrationTest def test_settings assert_routing( { :method => 'get', :path => "/settings" }, diff --git a/test/integration/routing/sys_test.rb b/test/integration/routing/sys_test.rb index 6b9afe63b..65a325367 100644 --- a/test/integration/routing/sys_test.rb +++ b/test/integration/routing/sys_test.rb @@ -17,7 +17,7 @@ require File.expand_path('../../../test_helper', __FILE__) -class RoutingSysTest < ActionController::IntegrationTest +class RoutingSysTest < ActionDispatch::IntegrationTest def test_sys assert_routing( { :method => 'get', :path => "/sys/projects" }, diff --git a/test/integration/routing/timelog_test.rb b/test/integration/routing/timelog_test.rb index 96bbfeb39..963e16975 100644 --- a/test/integration/routing/timelog_test.rb +++ b/test/integration/routing/timelog_test.rb @@ -17,7 +17,7 @@ require File.expand_path('../../../test_helper', __FILE__) -class RoutingTimelogsTest < ActionController::IntegrationTest +class RoutingTimelogsTest < ActionDispatch::IntegrationTest def test_timelogs_global assert_routing( { :method => 'get', :path => "/time_entries" }, diff --git a/test/integration/routing/trackers_test.rb b/test/integration/routing/trackers_test.rb index afefbee43..338197d8c 100644 --- a/test/integration/routing/trackers_test.rb +++ b/test/integration/routing/trackers_test.rb @@ -17,7 +17,7 @@ require File.expand_path('../../../test_helper', __FILE__) -class RoutingTrackersTest < ActionController::IntegrationTest +class RoutingTrackersTest < ActionDispatch::IntegrationTest def test_trackers assert_routing( { :method => 'get', :path => "/trackers" }, diff --git a/test/integration/routing/users_test.rb b/test/integration/routing/users_test.rb index db9a8dd64..dbdcbcc65 100644 --- a/test/integration/routing/users_test.rb +++ b/test/integration/routing/users_test.rb @@ -17,7 +17,7 @@ require File.expand_path('../../../test_helper', __FILE__) -class RoutingUsersTest < ActionController::IntegrationTest +class RoutingUsersTest < ActionDispatch::IntegrationTest def test_users assert_routing( { :method => 'get', :path => "/users" }, diff --git a/test/integration/routing/versions_test.rb b/test/integration/routing/versions_test.rb index d347603d0..28a7969c9 100644 --- a/test/integration/routing/versions_test.rb +++ b/test/integration/routing/versions_test.rb @@ -17,7 +17,7 @@ require File.expand_path('../../../test_helper', __FILE__) -class RoutingVersionsTest < ActionController::IntegrationTest +class RoutingVersionsTest < ActionDispatch::IntegrationTest def test_roadmap # /projects/foo/versions is /projects/foo/roadmap assert_routing( diff --git a/test/integration/routing/watchers_test.rb b/test/integration/routing/watchers_test.rb index 2715d7708..be35d5667 100644 --- a/test/integration/routing/watchers_test.rb +++ b/test/integration/routing/watchers_test.rb @@ -17,7 +17,7 @@ require File.expand_path('../../../test_helper', __FILE__) -class RoutingWatchersTest < ActionController::IntegrationTest +class RoutingWatchersTest < ActionDispatch::IntegrationTest def test_watchers assert_routing( { :method => 'get', :path => "/watchers/new" }, diff --git a/test/integration/routing/welcome_test.rb b/test/integration/routing/welcome_test.rb index f873002b0..2c2a32213 100644 --- a/test/integration/routing/welcome_test.rb +++ b/test/integration/routing/welcome_test.rb @@ -17,7 +17,7 @@ require File.expand_path('../../../test_helper', __FILE__) -class RoutingWelcomeTest < ActionController::IntegrationTest +class RoutingWelcomeTest < ActionDispatch::IntegrationTest def test_welcome assert_routing( { :method => 'get', :path => "/" }, diff --git a/test/integration/routing/wiki_test.rb b/test/integration/routing/wiki_test.rb index 0d1924758..f677856a8 100644 --- a/test/integration/routing/wiki_test.rb +++ b/test/integration/routing/wiki_test.rb @@ -17,7 +17,7 @@ require File.expand_path('../../../test_helper', __FILE__) -class RoutingWikiTest < ActionController::IntegrationTest +class RoutingWikiTest < ActionDispatch::IntegrationTest def test_wiki_matching assert_routing( { :method => 'get', :path => "/projects/567/wiki" }, @@ -54,7 +54,7 @@ class RoutingWikiTest < ActionController::IntegrationTest :id => 'CookBook_documentation', :version => '2' } ) # Make sure we don't route wiki page sub-uris to let plugins handle them - assert_raise(ActionController::RoutingError) do + assert_raise(Minitest::Assertion) do assert_recognizes({}, {:method => 'get', :path => "/projects/1/wiki/CookBook_documentation/whatever"}) end end diff --git a/test/integration/routing/wikis_test.rb b/test/integration/routing/wikis_test.rb index 1fbc6727b..98c83d0a0 100644 --- a/test/integration/routing/wikis_test.rb +++ b/test/integration/routing/wikis_test.rb @@ -17,7 +17,7 @@ require File.expand_path('../../../test_helper', __FILE__) -class RoutingWikisTest < ActionController::IntegrationTest +class RoutingWikisTest < ActionDispatch::IntegrationTest def test_wikis_plural_admin_setup ["get", "post"].each do |method| assert_routing( diff --git a/test/integration/routing/workflows_test.rb b/test/integration/routing/workflows_test.rb index cfa19a2f9..828b827e9 100644 --- a/test/integration/routing/workflows_test.rb +++ b/test/integration/routing/workflows_test.rb @@ -17,7 +17,7 @@ require File.expand_path('../../../test_helper', __FILE__) -class RoutingWorkflowsTest < ActionController::IntegrationTest +class RoutingWorkflowsTest < ActionDispatch::IntegrationTest def test_workflows assert_routing( { :method => 'get', :path => "/workflows" }, diff --git a/test/integration/users_test.rb b/test/integration/users_test.rb index 9b309c17e..de5e35e18 100644 --- a/test/integration/users_test.rb +++ b/test/integration/users_test.rb @@ -17,7 +17,7 @@ require File.expand_path('../../test_helper', __FILE__) -class UsersTest < ActionController::IntegrationTest +class UsersTest < ActionDispatch::IntegrationTest fixtures :users def test_destroy_should_not_accept_get_requests diff --git a/test/object_helpers.rb b/test/object_helpers.rb index 4e4a9fba3..1469e6aff 100644 --- a/test/object_helpers.rb +++ b/test/object_helpers.rb @@ -14,7 +14,7 @@ module ObjectHelpers def User.add_to_project(user, project, roles=nil) roles = Role.find(1) if roles.nil? - roles = [roles] unless roles.is_a?(Array) + roles = [roles] if roles.is_a?(Role) Member.create!(:principal => user, :project => project, :roles => roles) end @@ -178,14 +178,6 @@ module ObjectHelpers changeset.save! changeset end - - def Query.generate!(attributes={}) - query = new(attributes) - query.name = "Generated query" if query.name.blank? - query.user ||= User.find(1) - query.save! - query - end end module IssueObjectHelpers diff --git a/test/test_helper.rb b/test/test_helper.rb index 14f2d003f..20f7d50de 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -26,17 +26,25 @@ include ObjectHelpers require 'awesome_nested_set/version' +class ActionView::TestCase + helper :application + include ApplicationHelper +end + class ActiveSupport::TestCase include ActionDispatch::TestProcess + include Shoulda::Context::Assertions + include Shoulda::Context::InstanceMethods + extend Shoulda::Context::ClassMethods self.use_transactional_fixtures = true self.use_instantiated_fixtures = false - ESCAPED_CANT = 'can't' - ESCAPED_UCANT = 'Can't' + #ESCAPED_CANT = 'can't' + #ESCAPED_UCANT = 'Can't' # Rails 4.0.2 - #ESCAPED_CANT = 'can't' - #ESCAPED_UCANT = 'Can't' + ESCAPED_CANT = 'can't' + ESCAPED_UCANT = 'Can't' def log_user(login, password) User.anonymous @@ -147,7 +155,9 @@ class ActiveSupport::TestCase # Returns the path to the test +vendor+ repository def self.repository_path(vendor) - Rails.root.join("tmp/test/#{vendor.downcase}_repository").to_s + path = Rails.root.join("tmp/test/#{vendor.downcase}_repository").to_s + # Unlike ruby, JRuby returns Rails.root with backslashes under Windows + path.tr("\\", "/") end # Returns the url of the subversion test repository diff --git a/test/unit/changeset_test.rb b/test/unit/changeset_test.rb index 0467d59a1..eee7da81c 100644 --- a/test/unit/changeset_test.rb +++ b/test/unit/changeset_test.rb @@ -388,8 +388,7 @@ class ChangesetTest < ActiveSupport::TestCase def test_comments_should_be_converted_to_utf8 proj = Project.find(3) # str = File.read("#{RAILS_ROOT}/test/fixtures/encoding/iso-8859-1.txt") - str = "Texte encod\xe9 en ISO-8859-1." - str.force_encoding("ASCII-8BIT") if str.respond_to?(:force_encoding) + str = "Texte encod\xe9 en ISO-8859-1.".force_encoding("ASCII-8BIT") r = Repository::Bazaar.create!( :project => proj, :url => '/tmp/test/bazaar', @@ -401,18 +400,15 @@ class ChangesetTest < ActiveSupport::TestCase :scmid => '12345', :comments => str) assert( c.save ) - str_utf8 = "Texte encod\xc3\xa9 en ISO-8859-1." - str_utf8.force_encoding("UTF-8") if str_utf8.respond_to?(:force_encoding) + str_utf8 = "Texte encod\xc3\xa9 en ISO-8859-1.".force_encoding("UTF-8") assert_equal str_utf8, c.comments end def test_invalid_utf8_sequences_in_comments_should_be_replaced_latin1 proj = Project.find(3) # str = File.read("#{RAILS_ROOT}/test/fixtures/encoding/iso-8859-1.txt") - str1 = "Texte encod\xe9 en ISO-8859-1." - str2 = "\xe9a\xe9b\xe9c\xe9d\xe9e test" - str1.force_encoding("UTF-8") if str1.respond_to?(:force_encoding) - str2.force_encoding("ASCII-8BIT") if str2.respond_to?(:force_encoding) + str1 = "Texte encod\xe9 en ISO-8859-1.".force_encoding("UTF-8") + str2 = "\xe9a\xe9b\xe9c\xe9d\xe9e test".force_encoding("ASCII-8BIT") r = Repository::Bazaar.create!( :project => proj, :url => '/tmp/test/bazaar', @@ -431,10 +427,7 @@ class ChangesetTest < ActiveSupport::TestCase def test_invalid_utf8_sequences_in_comments_should_be_replaced_ja_jis proj = Project.find(3) - str = "test\xb5\xfetest\xb5\xfe" - if str.respond_to?(:force_encoding) - str.force_encoding('ASCII-8BIT') - end + str = "test\xb5\xfetest\xb5\xfe".force_encoding('ASCII-8BIT') r = Repository::Bazaar.create!( :project => proj, :url => '/tmp/test/bazaar', @@ -453,14 +446,12 @@ class ChangesetTest < ActiveSupport::TestCase s1 = "\xC2\x80" s2 = "\xc3\x82\xc2\x80" s4 = s2.dup - if s1.respond_to?(:force_encoding) - s3 = s1.dup - s1.force_encoding('ASCII-8BIT') - s2.force_encoding('ASCII-8BIT') - s3.force_encoding('ISO-8859-1') - s4.force_encoding('UTF-8') - assert_equal s3.encode('UTF-8'), s4 - end + s3 = s1.dup + s1.force_encoding('ASCII-8BIT') + s2.force_encoding('ASCII-8BIT') + s3.force_encoding('ISO-8859-1') + s4.force_encoding('UTF-8') + assert_equal s3.encode('UTF-8'), s4 proj = Project.find(3) r = Repository::Bazaar.create!( :project => proj, @@ -478,10 +469,8 @@ class ChangesetTest < ActiveSupport::TestCase def test_invalid_utf8_sequences_in_paths_should_be_replaced proj = Project.find(3) - str1 = "Texte encod\xe9 en ISO-8859-1" - str2 = "\xe9a\xe9b\xe9c\xe9d\xe9e test" - str1.force_encoding("UTF-8") if str1.respond_to?(:force_encoding) - str2.force_encoding("ASCII-8BIT") if str2.respond_to?(:force_encoding) + str1 = "Texte encod\xe9 en ISO-8859-1".force_encoding("UTF-8") + str2 = "\xe9a\xe9b\xe9c\xe9d\xe9e test".force_encoding("ASCII-8BIT") r = Repository::Bazaar.create!( :project => proj, :url => '/tmp/test/bazaar', @@ -521,9 +510,7 @@ class ChangesetTest < ActiveSupport::TestCase assert( c.save ) assert_equal "", c.comments assert_equal nil, c.committer - if c.comments.respond_to?(:force_encoding) - assert_equal "UTF-8", c.comments.encoding.to_s - end + assert_equal "UTF-8", c.comments.encoding.to_s end def test_comments_empty @@ -542,10 +529,8 @@ class ChangesetTest < ActiveSupport::TestCase assert( c.save ) assert_equal "", c.comments assert_equal "", c.committer - if c.comments.respond_to?(:force_encoding) - assert_equal "UTF-8", c.comments.encoding.to_s - assert_equal "UTF-8", c.committer.encoding.to_s - end + assert_equal "UTF-8", c.comments.encoding.to_s + assert_equal "UTF-8", c.committer.encoding.to_s end def test_comments_should_accept_more_than_64k diff --git a/test/unit/custom_field_test.rb b/test/unit/custom_field_test.rb index 7814061f1..56cdbcb72 100644 --- a/test/unit/custom_field_test.rb +++ b/test/unit/custom_field_test.rb @@ -95,14 +95,12 @@ class CustomFieldTest < ActiveSupport::TestCase assert_equal ["One value", "And another one"], field.possible_values end - if "string".respond_to?(:encoding) - def test_possible_values_stored_as_binary_should_be_utf8_encoded - field = CustomField.find(11) - assert_kind_of Array, field.possible_values - assert field.possible_values.size > 0 - field.possible_values.each do |value| - assert_equal "UTF-8", value.encoding.name - end + def test_possible_values_stored_as_binary_should_be_utf8_encoded + field = CustomField.find(11) + assert_kind_of Array, field.possible_values + assert field.possible_values.size > 0 + field.possible_values.each do |value| + assert_equal "UTF-8", value.encoding.name end end diff --git a/test/unit/enabled_module_test.rb b/test/unit/enabled_module_test.rb index b4c7acebc..918d53e48 100644 --- a/test/unit/enabled_module_test.rb +++ b/test/unit/enabled_module_test.rb @@ -22,7 +22,7 @@ class EnabledModuleTest < ActiveSupport::TestCase def test_enabling_wiki_should_create_a_wiki CustomField.delete_all - project = Project.create!(:name => 'Project with wiki', :identifier => 'wikiproject') + project = Project.create!(:name => 'Project with wiki', :identifier => 'wikiproject', :enabled_module_names => []) assert_nil project.wiki project.enabled_module_names = ['wiki'] project.reload diff --git a/test/unit/group_test.rb b/test/unit/group_test.rb index fa5ded8f1..d2f09f9a7 100644 --- a/test/unit/group_test.rb +++ b/test/unit/group_test.rb @@ -52,8 +52,7 @@ class GroupTest < ActiveSupport::TestCase def test_blank_name_error_message_fr set_language_if_valid 'fr' - str = "Nom doit \xc3\xaatre renseign\xc3\xa9(e)" - str.force_encoding('UTF-8') if str.respond_to?(:force_encoding) + str = "Nom doit \xc3\xaatre renseign\xc3\xa9(e)".force_encoding('UTF-8') g = Group.new assert !g.save assert_include str, g.errors.full_messages @@ -133,20 +132,4 @@ class GroupTest < ActiveSupport::TestCase assert_equal nil, Issue.find(1).assigned_to_id end - - def test_builtin_id_with_anonymous_user_should_return_anonymous_group - assert_equal 13, Group.builtin_id(User.anonymous) - end - - def test_builtin_id_with_anonymous_role_should_return_anonymous_group - assert_equal 13, Group.builtin_id(Role.anonymous) - end - - def test_builtin_id_with_user_should_return_non_member_group - assert_equal 12, Group.builtin_id(User.find(1)) - end - - def test_builtin_id_with_non_member_role_should_return_non_member_group - assert_equal 12, Group.builtin_id(Role.non_member) - end end diff --git a/test/unit/helpers/application_helper_test.rb b/test/unit/helpers/application_helper_test.rb index 0bdcba359..6ce52ed72 100644 --- a/test/unit/helpers/application_helper_test.rb +++ b/test/unit/helpers/application_helper_test.rb @@ -35,10 +35,7 @@ class ApplicationHelperTest < ActionView::TestCase def setup super set_tmp_attachments_directory - @russian_test = "\xd1\x82\xd0\xb5\xd1\x81\xd1\x82" - if @russian_test.respond_to?(:force_encoding) - @russian_test.force_encoding('UTF-8') - end + @russian_test = "\xd1\x82\xd0\xb5\xd1\x81\xd1\x82".force_encoding('UTF-8') end test "#link_to_if_authorized for authorized user should allow using the :controller and :action for the target link" do @@ -99,16 +96,12 @@ class ApplicationHelperTest < ActionView::TestCase to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) } end - if 'ruby'.respond_to?(:encoding) - def test_auto_links_with_non_ascii_characters - to_test = { - "http://foo.bar/#{@russian_test}" => - %|<a class="external" href="http://foo.bar/#{@russian_test}">http://foo.bar/#{@russian_test}</a>| - } - to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) } - end - else - puts 'Skipping test_auto_links_with_non_ascii_characters, unsupported ruby version' + def test_auto_links_with_non_ascii_characters + to_test = { + "http://foo.bar/#{@russian_test}" => + %|<a class="external" href="http://foo.bar/#{@russian_test}">http://foo.bar/#{@russian_test}</a>| + } + to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) } end def test_auto_mailto @@ -254,16 +247,12 @@ RAW to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) } end - if 'ruby'.respond_to?(:encoding) - def test_textile_external_links_with_non_ascii_characters - to_test = { - %|This is a "link":http://foo.bar/#{@russian_test}| => - %|This is a <a href="http://foo.bar/#{@russian_test}" class="external">link</a>| - } - to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) } - end - else - puts 'Skipping test_textile_external_links_with_non_ascii_characters, unsupported ruby version' + def test_textile_external_links_with_non_ascii_characters + to_test = { + %|This is a "link":http://foo.bar/#{@russian_test}| => + %|This is a <a href="http://foo.bar/#{@russian_test}" class="external">link</a>| + } + to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) } end def test_redmine_links @@ -1336,13 +1325,8 @@ RAW project = Project.find(1) assert_equal %(<a href="/projects/ecookbook">eCookbook</a>), link_to_project(project) - assert_equal %(<a href="/projects/ecookbook/settings">eCookbook</a>), - link_to_project(project, :action => 'settings') assert_equal %(<a href="http://test.host/projects/ecookbook?jump=blah">eCookbook</a>), link_to_project(project, {:only_path => false, :jump => 'blah'}) - result = link_to("eCookbook", "/projects/ecookbook/settings", :class => "project") - assert_equal result, - link_to_project(project, {:action => 'settings'}, :class => "project") end def test_link_to_project_settings @@ -1433,7 +1417,7 @@ RAW def test_raw_json_should_escape_closing_tags s = raw_json(["<foo>bar</foo>"]) - assert_equal '["<foo>bar<\/foo>"]', s + assert_include '\/foo', s end def test_raw_json_should_be_html_safe @@ -1508,8 +1492,7 @@ RAW end def test_truncate_single_line_non_ascii - ja = "\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e" - ja.force_encoding('UTF-8') if ja.respond_to?(:force_encoding) + ja = "\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e".force_encoding('UTF-8') result = truncate_single_line_raw("#{ja}\n#{ja}\n#{ja}", 10) assert_equal "#{ja} #{ja}...", result assert !result.html_safe? diff --git a/test/unit/helpers/projects_helper_test.rb b/test/unit/helpers/projects_helper_test.rb index b4db5d42f..20f4283fe 100644 --- a/test/unit/helpers/projects_helper_test.rb +++ b/test/unit/helpers/projects_helper_test.rb @@ -42,23 +42,16 @@ class ProjectsHelperTest < ActionView::TestCase def test_link_to_version_within_project @project = Project.find(2) User.current = User.find(1) - assert_equal '<a href="/versions/5" title="07/01/2006">Alpha</a>', link_to_version(Version.find(5)) + assert_equal '<a href="/versions/5">Alpha</a>', link_to_version(Version.find(5)) end def test_link_to_version User.current = User.find(1) - assert_equal '<a href="/versions/5" title="07/01/2006">Alpha</a>', link_to_version(Version.find(5)) - end - - def test_link_to_version_without_effective_date - User.current = User.find(1) - version = Version.find(5) - version.effective_date = nil - assert_equal '<a href="/versions/5">Alpha</a>', link_to_version(version) + assert_equal '<a href="/versions/5">OnlineStore - Alpha</a>', link_to_version(Version.find(5)) end def test_link_to_private_version - assert_equal 'Alpha', link_to_version(Version.find(5)) + assert_equal 'OnlineStore - Alpha', link_to_version(Version.find(5)) end def test_link_to_version_invalid_version @@ -71,20 +64,11 @@ class ProjectsHelperTest < ActionView::TestCase end def test_format_version_name - assert_equal "0.1", format_version_name(Version.find(1)) - end - - def test_format_version_name_for_shared_version_within_project_should_not_display_project_name - @project = Project.find(1) - version = Version.find(1) - version.sharing = 'system' - assert_equal "0.1", format_version_name(version) + assert_equal "eCookbook - 0.1", format_version_name(Version.find(1)) end - def test_format_version_name_for_shared_version_should_display_project_name - version = Version.find(1) - version.sharing = 'system' - assert_equal "eCookbook - 0.1", format_version_name(version) + def test_format_version_name_for_system_version + assert_equal "OnlineStore - Systemwide visible version", format_version_name(Version.find(7)) end def test_version_options_for_select_with_no_versions diff --git a/test/unit/initializers/patches_test.rb b/test/unit/initializers/patches_test.rb index ac4b12b43..2b761a427 100644 --- a/test/unit/initializers/patches_test.rb +++ b/test/unit/initializers/patches_test.rb @@ -47,21 +47,19 @@ class PatchesTest < ActiveSupport::TestCase end # https://github.com/rails/rails/pull/14198/files - if RUBY_VERSION >= "1.9" - def test_indifferent_select - hash = ActiveSupport::HashWithIndifferentAccess.new(@symbols).select { |_ ,v| v == 1 } - assert_equal({ 'a' => 1 }, hash) - assert_instance_of ((Rails::VERSION::MAJOR < 4 && RUBY_VERSION < "2.1") ? - Hash : ActiveSupport::HashWithIndifferentAccess), - hash - end + def test_indifferent_select + hash = ActiveSupport::HashWithIndifferentAccess.new(@symbols).select { |_ ,v| v == 1 } + assert_equal({ 'a' => 1 }, hash) + assert_instance_of ((Rails::VERSION::MAJOR < 4 && RUBY_VERSION < "2.1") ? + Hash : ActiveSupport::HashWithIndifferentAccess), + hash + end - def test_indifferent_select_bang - indifferent_strings = ActiveSupport::HashWithIndifferentAccess.new(@symbols) - indifferent_strings.select! { |_, v| v == 1 } - assert_equal({ 'a' => 1 }, indifferent_strings) - assert_instance_of ActiveSupport::HashWithIndifferentAccess, indifferent_strings - end + def test_indifferent_select_bang + indifferent_strings = ActiveSupport::HashWithIndifferentAccess.new(@symbols) + indifferent_strings.select! { |_, v| v == 1 } + assert_equal({ 'a' => 1 }, indifferent_strings) + assert_instance_of ActiveSupport::HashWithIndifferentAccess, indifferent_strings end def test_indifferent_reject @@ -77,15 +75,13 @@ class PatchesTest < ActiveSupport::TestCase assert_instance_of ActiveSupport::HashWithIndifferentAccess, indifferent_strings end - if RUBY_VERSION >= "1.9" - def test_select - assert_equal @keys, @ordered_hash.select { true }.map(&:first) - new_ordered_hash = @ordered_hash.select { true } - assert_equal @keys, new_ordered_hash.map(&:first) - assert_instance_of ((Rails::VERSION::MAJOR < 4 && RUBY_VERSION < "2.1") ? - Hash : ActiveSupport::OrderedHash), - new_ordered_hash - end + def test_select + assert_equal @keys, @ordered_hash.select { true }.map(&:first) + new_ordered_hash = @ordered_hash.select { true } + assert_equal @keys, new_ordered_hash.map(&:first) + assert_instance_of ((Rails::VERSION::MAJOR < 4 && RUBY_VERSION < "2.1") ? + Hash : ActiveSupport::OrderedHash), + new_ordered_hash end def test_reject diff --git a/test/unit/issue_nested_set_test.rb b/test/unit/issue_nested_set_test.rb index 5b540e588..d31acdee2 100644 --- a/test/unit/issue_nested_set_test.rb +++ b/test/unit/issue_nested_set_test.rb @@ -416,7 +416,7 @@ class IssueNestedSetTest < ActiveSupport::TestCase c.reload assert_equal 5, c.issues.count - ic1, ic2, ic3, ic4, ic5 = c.issues.order('subject').all + ic1, ic2, ic3, ic4, ic5 = c.issues.order('subject').to_a assert ic1.root? assert_equal ic1, ic2.parent assert_equal ic1, ic3.parent diff --git a/test/unit/issue_priority_test.rb b/test/unit/issue_priority_test.rb index f9c0c9793..7c4a38061 100644 --- a/test/unit/issue_priority_test.rb +++ b/test/unit/issue_priority_test.rb @@ -83,7 +83,7 @@ class IssuePriorityTest < ActiveSupport::TestCase IssuePriority.clear_position_names IssuePriority.compute_position_names - assert_equal %w(lowest default high3 high2 highest), IssuePriority.active.all.sort.map(&:position_name) + assert_equal %w(lowest default high3 high2 highest), IssuePriority.active.to_a.sort.map(&:position_name) end def test_compute_position_names_without_default_priority_should_split_priorities @@ -91,16 +91,16 @@ class IssuePriorityTest < ActiveSupport::TestCase IssuePriority.update_all :is_default => false IssuePriority.compute_position_names - assert_equal %w(lowest low2 default high2 highest), IssuePriority.active.all.sort.map(&:position_name) + assert_equal %w(lowest low2 default high2 highest), IssuePriority.active.to_a.sort.map(&:position_name) end def test_adding_a_priority_should_update_position_names priority = IssuePriority.create!(:name => 'New') - assert_equal %w(lowest default high4 high3 high2 highest), IssuePriority.active.all.sort.map(&:position_name) + assert_equal %w(lowest default high4 high3 high2 highest), IssuePriority.active.to_a.sort.map(&:position_name) end def test_destroying_a_priority_should_update_position_names IssuePriority.find_by_position_name('highest').destroy - assert_equal %w(lowest default high2 highest), IssuePriority.active.all.sort.map(&:position_name) + assert_equal %w(lowest default high2 highest), IssuePriority.active.to_a.sort.map(&:position_name) end end diff --git a/test/unit/issue_status_test.rb b/test/unit/issue_status_test.rb index f9855af53..387fa16a6 100644 --- a/test/unit/issue_status_test.rb +++ b/test/unit/issue_status_test.rb @@ -112,7 +112,7 @@ class IssueStatusTest < ActiveSupport::TestCase end def test_sorted_scope - assert_equal IssueStatus.all.sort, IssueStatus.sorted.all + assert_equal IssueStatus.all.sort, IssueStatus.sorted.to_a end def test_named_scope diff --git a/test/unit/issue_test.rb b/test/unit/issue_test.rb index 3454c71f5..2cf00f5ff 100644 --- a/test/unit/issue_test.rb +++ b/test/unit/issue_test.rb @@ -204,7 +204,7 @@ class IssueTest < ActiveSupport::TestCase def test_visible_scope_for_anonymous # Anonymous user should see issues of public projects only - issues = Issue.visible(User.anonymous).all + issues = Issue.visible(User.anonymous).to_a assert issues.any? assert_nil issues.detect {|issue| !issue.project.is_public?} assert_nil issues.detect {|issue| issue.is_private?} @@ -214,7 +214,7 @@ class IssueTest < ActiveSupport::TestCase def test_visible_scope_for_anonymous_without_view_issues_permissions # Anonymous user should not see issues without permission Role.anonymous.remove_permission!(:view_issues) - issues = Issue.visible(User.anonymous).all + issues = Issue.visible(User.anonymous).to_a assert issues.empty? assert_visibility_match User.anonymous, issues end @@ -247,7 +247,7 @@ class IssueTest < ActiveSupport::TestCase user = User.find(9) assert user.projects.empty? # Non member user should see issues of public projects only - issues = Issue.visible(user).all + issues = Issue.visible(user).to_a assert issues.any? assert_nil issues.detect {|issue| !issue.project.is_public?} assert_nil issues.detect {|issue| issue.is_private?} @@ -259,7 +259,7 @@ class IssueTest < ActiveSupport::TestCase Issue.create!(:project_id => 1, :tracker_id => 1, :author_id => 9, :subject => 'Issue by non member') user = User.find(9) - issues = Issue.visible(user).all + issues = Issue.visible(user).to_a assert issues.any? assert_nil issues.detect {|issue| issue.author != user} assert_visibility_match user, issues @@ -270,7 +270,7 @@ class IssueTest < ActiveSupport::TestCase Role.non_member.remove_permission!(:view_issues) user = User.find(9) assert user.projects.empty? - issues = Issue.visible(user).all + issues = Issue.visible(user).to_a assert issues.empty? assert_visibility_match user, issues end @@ -291,7 +291,7 @@ class IssueTest < ActiveSupport::TestCase # User should see issues of projects for which user has view_issues permissions only Role.non_member.remove_permission!(:view_issues) Member.create!(:principal => user, :project_id => 3, :role_ids => [2]) - issues = Issue.visible(user).all + issues = Issue.visible(user).to_a assert issues.any? assert_nil issues.detect {|issue| issue.project_id != 3} assert_nil issues.detect {|issue| issue.is_private?} @@ -311,12 +311,12 @@ class IssueTest < ActiveSupport::TestCase :is_private => true) Role.find(2).update_attribute :issues_visibility, 'default' - issues = Issue.visible(User.find(8)).all + issues = Issue.visible(User.find(8)).to_a assert issues.any? assert issues.include?(issue) Role.find(2).update_attribute :issues_visibility, 'own' - issues = Issue.visible(User.find(8)).all + issues = Issue.visible(User.find(8)).to_a assert issues.any? assert issues.include?(issue) end @@ -325,7 +325,7 @@ class IssueTest < ActiveSupport::TestCase user = User.find(1) user.members.each(&:destroy) assert user.projects.empty? - issues = Issue.visible(user).all + issues = Issue.visible(user).to_a assert issues.any? # Admin should see issues on private projects that admin does not belong to assert issues.detect {|issue| !issue.project.is_public?} @@ -336,7 +336,7 @@ class IssueTest < ActiveSupport::TestCase def test_visible_scope_with_project project = Project.find(1) - issues = Issue.visible(User.find(2), :project => project).all + issues = Issue.visible(User.find(2), :project => project).to_a projects = issues.collect(&:project).uniq assert_equal 1, projects.size assert_equal project, projects.first @@ -344,7 +344,7 @@ class IssueTest < ActiveSupport::TestCase def test_visible_scope_with_project_and_subprojects project = Project.find(1) - issues = Issue.visible(User.find(2), :project => project, :with_subprojects => true).all + issues = Issue.visible(User.find(2), :project => project, :with_subprojects => true).to_a projects = issues.collect(&:project).uniq assert projects.size > 1 assert_equal [], projects.select {|p| !p.is_or_is_descendant_of?(project)} @@ -370,13 +370,20 @@ class IssueTest < ActiveSupport::TestCase assert_equal 2, parent.descendants.visible(user).collect{|i| i}.size end + def test_visible_scope_with_unsaved_user_should_not_raise_an_error + user = User.new + assert_nothing_raised do + Issue.visible(user).to_a + end + end + def test_open_scope - issues = Issue.open.all + issues = Issue.open.to_a assert_nil issues.detect(&:closed?) end def test_open_scope_with_arg - issues = Issue.open(false).all + issues = Issue.open(false).to_a assert_equal issues, issues.select(&:closed?) end @@ -1289,7 +1296,7 @@ class IssueTest < ActiveSupport::TestCase end test "#copy should not create a journal" do - copy = Issue.find(1).copy(:project_id => 3, :tracker_id => 2, :assigned_to_id => 3) + copy = Issue.find(1).copy({:project_id => 3, :tracker_id => 2, :assigned_to_id => 3}, :link => false) copy.save! assert_equal 0, copy.reload.journals.size end @@ -1325,7 +1332,7 @@ class IssueTest < ActiveSupport::TestCase test "#copy should create a journal with notes" do date = Date.today notes = "Notes added when copying" - copy = Issue.find(1).copy(:project_id => 3, :tracker_id => 2, :start_date => date) + copy = Issue.find(1).copy({:project_id => 3, :tracker_id => 2, :start_date => date}, :link => false) copy.init_journal(User.current, notes) copy.save! @@ -1619,13 +1626,15 @@ class IssueTest < ActiveSupport::TestCase issue2.reload assert_equal Date.parse('2012-10-18'), issue2.start_date - child = Issue.new(:parent_issue_id => issue2.id, :start_date => '2012-10-16', - :project_id => 1, :tracker_id => 1, :status_id => 1, :subject => 'Child', :author_id => 1) - assert !child.valid? - assert_include 'Start date cannot be earlier than 10/18/2012 because of preceding issues', child.errors.full_messages - assert_equal Date.parse('2012-10-18'), child.soonest_start - child.start_date = '2012-10-18' - assert child.save + with_settings :date_format => '%m/%d/%Y' do + child = Issue.new(:parent_issue_id => issue2.id, :start_date => '2012-10-16', + :project_id => 1, :tracker_id => 1, :status_id => 1, :subject => 'Child', :author_id => 1) + assert !child.valid? + assert_include 'Start date cannot be earlier than 10/18/2012 because of preceding issues', child.errors.full_messages + assert_equal Date.parse('2012-10-18'), child.soonest_start + child.start_date = '2012-10-18' + assert child.save + end end def test_setting_parent_to_a_dependent_issue_should_not_validate diff --git a/test/unit/journal_test.rb b/test/unit/journal_test.rb index ccfd2635f..36f494807 100644 --- a/test/unit/journal_test.rb +++ b/test/unit/journal_test.rb @@ -27,6 +27,7 @@ class JournalTest < ActiveSupport::TestCase def setup @journal = Journal.find 1 + User.current = nil end def test_journalized_is_an_issue @@ -119,12 +120,12 @@ class JournalTest < ActiveSupport::TestCase def test_visible_scope_for_anonymous # Anonymous user should see issues of public projects only - journals = Journal.visible(User.anonymous).all + journals = Journal.visible(User.anonymous).to_a assert journals.any? assert_nil journals.detect {|journal| !journal.issue.project.is_public?} # Anonymous user should not see issues without permission Role.anonymous.remove_permission!(:view_issues) - journals = Journal.visible(User.anonymous).all + journals = Journal.visible(User.anonymous).to_a assert journals.empty? end @@ -132,18 +133,18 @@ class JournalTest < ActiveSupport::TestCase user = User.find(9) assert user.projects.empty? # Non member user should see issues of public projects only - journals = Journal.visible(user).all + journals = Journal.visible(user).to_a assert journals.any? assert_nil journals.detect {|journal| !journal.issue.project.is_public?} # Non member user should not see issues without permission Role.non_member.remove_permission!(:view_issues) user.reload - journals = Journal.visible(user).all + journals = Journal.visible(user).to_a assert journals.empty? # User should see issues of projects for which user has view_issues permissions only Member.create!(:principal => user, :project_id => 1, :role_ids => [1]) user.reload - journals = Journal.visible(user).all + journals = Journal.visible(user).to_a assert journals.any? assert_nil journals.detect {|journal| journal.issue.project_id != 1} end @@ -152,7 +153,7 @@ class JournalTest < ActiveSupport::TestCase user = User.find(1) user.members.each(&:destroy) assert user.projects.empty? - journals = Journal.visible(user).all + journals = Journal.visible(user).to_a assert journals.any? # Admin should see issues on private projects that admin does not belong to assert journals.detect {|journal| !journal.issue.project.is_public?} diff --git a/test/unit/lib/redmine/codeset_util_test.rb b/test/unit/lib/redmine/codeset_util_test.rb index 496ab5f09..0758ec485 100644 --- a/test/unit/lib/redmine/codeset_util_test.rb +++ b/test/unit/lib/redmine/codeset_util_test.rb @@ -21,14 +21,9 @@ class Redmine::CodesetUtilTest < ActiveSupport::TestCase def test_to_utf8_by_setting_from_latin1 with_settings :repositories_encodings => 'UTF-8,ISO-8859-1' do - s1 = "Texte encod\xc3\xa9" - s2 = "Texte encod\xe9" - s3 = s2.dup - if s1.respond_to?(:force_encoding) - s1.force_encoding("UTF-8") - s2.force_encoding("ASCII-8BIT") - s3.force_encoding("UTF-8") - end + s1 = "Texte encod\xc3\xa9".force_encoding("UTF-8") + s2 = "Texte encod\xe9".force_encoding("ASCII-8BIT") + s3 = s2.dup.force_encoding("UTF-8") assert_equal s1, Redmine::CodesetUtil.to_utf8_by_setting(s2) assert_equal s1, Redmine::CodesetUtil.to_utf8_by_setting(s3) end @@ -36,14 +31,9 @@ class Redmine::CodesetUtilTest < ActiveSupport::TestCase def test_to_utf8_by_setting_from_euc_jp with_settings :repositories_encodings => 'UTF-8,EUC-JP' do - s1 = "\xe3\x83\xac\xe3\x83\x83\xe3\x83\x89\xe3\x83\x9e\xe3\x82\xa4\xe3\x83\xb3" - s2 = "\xa5\xec\xa5\xc3\xa5\xc9\xa5\xde\xa5\xa4\xa5\xf3" - s3 = s2.dup - if s1.respond_to?(:force_encoding) - s1.force_encoding("UTF-8") - s2.force_encoding("ASCII-8BIT") - s3.force_encoding("UTF-8") - end + s1 = "\xe3\x83\xac\xe3\x83\x83\xe3\x83\x89\xe3\x83\x9e\xe3\x82\xa4\xe3\x83\xb3".force_encoding("UTF-8") + s2 = "\xa5\xec\xa5\xc3\xa5\xc9\xa5\xde\xa5\xa4\xa5\xf3".force_encoding("ASCII-8BIT") + s3 = s2.dup.force_encoding("UTF-8") assert_equal s1, Redmine::CodesetUtil.to_utf8_by_setting(s2) assert_equal s1, Redmine::CodesetUtil.to_utf8_by_setting(s3) end @@ -51,14 +41,9 @@ class Redmine::CodesetUtilTest < ActiveSupport::TestCase def test_to_utf8_by_setting_should_be_converted_all_latin1 with_settings :repositories_encodings => 'ISO-8859-1' do - s1 = "\xc3\x82\xc2\x80" - s2 = "\xC2\x80" - s3 = s2.dup - if s1.respond_to?(:force_encoding) - s1.force_encoding("UTF-8") - s2.force_encoding("ASCII-8BIT") - s3.force_encoding("UTF-8") - end + s1 = "\xc3\x82\xc2\x80".force_encoding("UTF-8") + s2 = "\xC2\x80".force_encoding("ASCII-8BIT") + s3 = s2.dup.force_encoding("UTF-8") assert_equal s1, Redmine::CodesetUtil.to_utf8_by_setting(s2) assert_equal s1, Redmine::CodesetUtil.to_utf8_by_setting(s3) end @@ -70,45 +55,33 @@ class Redmine::CodesetUtilTest < ActiveSupport::TestCase end def test_to_utf8_by_setting_returns_ascii_as_utf8 - s1 = "ASCII" - s2 = s1.dup - if s1.respond_to?(:force_encoding) - s1.force_encoding("UTF-8") - s2.force_encoding("ISO-8859-1") - end + s1 = "ASCII".force_encoding("UTF-8") + s2 = s1.dup.force_encoding("ISO-8859-1") str1 = Redmine::CodesetUtil.to_utf8_by_setting(s1) str2 = Redmine::CodesetUtil.to_utf8_by_setting(s2) assert_equal s1, str1 assert_equal s1, str2 - if s1.respond_to?(:force_encoding) - assert_equal "UTF-8", str1.encoding.to_s - assert_equal "UTF-8", str2.encoding.to_s - end + assert_equal "UTF-8", str1.encoding.to_s + assert_equal "UTF-8", str2.encoding.to_s end def test_to_utf8_by_setting_invalid_utf8_sequences_should_be_stripped with_settings :repositories_encodings => '' do # s1 = File.read("#{RAILS_ROOT}/test/fixtures/encoding/iso-8859-1.txt") - s1 = "Texte encod\xe9 en ISO-8859-1." - s1.force_encoding("ASCII-8BIT") if s1.respond_to?(:force_encoding) + s1 = "Texte encod\xe9 en ISO-8859-1.".force_encoding("ASCII-8BIT") str = Redmine::CodesetUtil.to_utf8_by_setting(s1) - if str.respond_to?(:force_encoding) - assert str.valid_encoding? - assert_equal "UTF-8", str.encoding.to_s - end + assert str.valid_encoding? + assert_equal "UTF-8", str.encoding.to_s assert_equal "Texte encod? en ISO-8859-1.", str end end def test_to_utf8_by_setting_invalid_utf8_sequences_should_be_stripped_ja_jis with_settings :repositories_encodings => 'ISO-2022-JP' do - s1 = "test\xb5\xfetest\xb5\xfe" - s1.force_encoding("ASCII-8BIT") if s1.respond_to?(:force_encoding) + s1 = "test\xb5\xfetest\xb5\xfe".force_encoding("ASCII-8BIT") str = Redmine::CodesetUtil.to_utf8_by_setting(s1) - if str.respond_to?(:force_encoding) - assert str.valid_encoding? - assert_equal "UTF-8", str.encoding.to_s - end + assert str.valid_encoding? + assert_equal "UTF-8", str.encoding.to_s assert_equal "test??test??", str end end diff --git a/test/unit/lib/redmine/export/pdf_test.rb b/test/unit/lib/redmine/export/pdf_test.rb index a0821d62d..8af672660 100644 --- a/test/unit/lib/redmine/export/pdf_test.rb +++ b/test/unit/lib/redmine/export/pdf_test.rb @@ -27,11 +27,10 @@ class PdfTest < ActiveSupport::TestCase end def test_rdm_pdf_iconv_cannot_convert_ja_cp932 - encoding = ( RUBY_PLATFORM == 'java' ? "SJIS" : "CP932" ) utf8_txt_1 = "\xe7\x8b\x80\xe6\x85\x8b" utf8_txt_2 = "\xe7\x8b\x80\xe6\x85\x8b\xe7\x8b\x80" utf8_txt_3 = "\xe7\x8b\x80\xe7\x8b\x80\xe6\x85\x8b\xe7\x8b\x80" - if utf8_txt_1.respond_to?(:force_encoding) + ["CP932", "SJIS"].each do |encoding| txt_1 = Redmine::Export::PDF::RDMPdfEncoding::rdm_from_utf8(utf8_txt_1, encoding) txt_2 = Redmine::Export::PDF::RDMPdfEncoding::rdm_from_utf8(utf8_txt_2, encoding) txt_3 = Redmine::Export::PDF::RDMPdfEncoding::rdm_from_utf8(utf8_txt_3, encoding) @@ -41,88 +40,65 @@ class PdfTest < ActiveSupport::TestCase assert_equal "ASCII-8BIT", txt_1.encoding.to_s assert_equal "ASCII-8BIT", txt_2.encoding.to_s assert_equal "ASCII-8BIT", txt_3.encoding.to_s - elsif RUBY_PLATFORM == 'java' - assert_equal "??", - Redmine::Export::PDF::RDMPdfEncoding::rdm_from_utf8(utf8_txt_1, encoding) - assert_equal "???", - Redmine::Export::PDF::RDMPdfEncoding::rdm_from_utf8(utf8_txt_2, encoding) - assert_equal "????", - Redmine::Export::PDF::RDMPdfEncoding::rdm_from_utf8(utf8_txt_3, encoding) - else - assert_equal "???\x91\xd4", - Redmine::Export::PDF::RDMPdfEncoding::rdm_from_utf8(utf8_txt_1, encoding) - assert_equal "???\x91\xd4???", - Redmine::Export::PDF::RDMPdfEncoding::rdm_from_utf8(utf8_txt_2, encoding) - assert_equal "??????\x91\xd4???", - Redmine::Export::PDF::RDMPdfEncoding::rdm_from_utf8(utf8_txt_3, encoding) end end def test_rdm_pdf_iconv_invalid_utf8_should_be_replaced_en - str1 = "Texte encod\xe9 en ISO-8859-1" - str2 = "\xe9a\xe9b\xe9c\xe9d\xe9e test" - str1.force_encoding("UTF-8") if str1.respond_to?(:force_encoding) - str2.force_encoding("ASCII-8BIT") if str2.respond_to?(:force_encoding) + str1 = "Texte encod\xe9 en ISO-8859-1".force_encoding("UTF-8") + str2 = "\xe9a\xe9b\xe9c\xe9d\xe9e test".force_encoding("ASCII-8BIT") txt_1 = Redmine::Export::PDF::RDMPdfEncoding::rdm_from_utf8(str1, 'UTF-8') txt_2 = Redmine::Export::PDF::RDMPdfEncoding::rdm_from_utf8(str2, 'UTF-8') - if txt_1.respond_to?(:force_encoding) - assert_equal "ASCII-8BIT", txt_1.encoding.to_s - assert_equal "ASCII-8BIT", txt_2.encoding.to_s - end + assert_equal "ASCII-8BIT", txt_1.encoding.to_s + assert_equal "ASCII-8BIT", txt_2.encoding.to_s assert_equal "Texte encod? en ISO-8859-1", txt_1 assert_equal "?a?b?c?d?e test", txt_2 end def test_rdm_pdf_iconv_invalid_utf8_should_be_replaced_ja - str1 = "Texte encod\xe9 en ISO-8859-1" - str2 = "\xe9a\xe9b\xe9c\xe9d\xe9e test" - str1.force_encoding("UTF-8") if str1.respond_to?(:force_encoding) - str2.force_encoding("ASCII-8BIT") if str2.respond_to?(:force_encoding) + str1 = "Texte encod\xe9 en ISO-8859-1".force_encoding("UTF-8") + str2 = "\xe9a\xe9b\xe9c\xe9d\xe9e test".force_encoding("ASCII-8BIT") encoding = ( RUBY_PLATFORM == 'java' ? "SJIS" : "CP932" ) txt_1 = Redmine::Export::PDF::RDMPdfEncoding::rdm_from_utf8(str1, encoding) txt_2 = Redmine::Export::PDF::RDMPdfEncoding::rdm_from_utf8(str2, encoding) - if txt_1.respond_to?(:force_encoding) - assert_equal "ASCII-8BIT", txt_1.encoding.to_s - assert_equal "ASCII-8BIT", txt_2.encoding.to_s - end + assert_equal "ASCII-8BIT", txt_1.encoding.to_s + assert_equal "ASCII-8BIT", txt_2.encoding.to_s assert_equal "Texte encod? en ISO-8859-1", txt_1 assert_equal "?a?b?c?d?e test", txt_2 end def test_attach - set_fixtures_attachments_directory + ["CP932", "SJIS"].each do |encoding| + set_fixtures_attachments_directory - str2 = "\x83e\x83X\x83g" - str2.force_encoding("ASCII-8BIT") if str2.respond_to?(:force_encoding) - encoding = ( RUBY_PLATFORM == 'java' ? "SJIS" : "CP932" ) + str2 = "\x83e\x83X\x83g".force_encoding("ASCII-8BIT") - a1 = Attachment.find(17) - a2 = Attachment.find(19) + a1 = Attachment.find(17) + a2 = Attachment.find(19) + User.current = User.find(1) + assert a1.readable? + assert a1.visible? + assert a2.readable? + assert a2.visible? - User.current = User.find(1) - assert a1.readable? - assert a1.visible? - assert a2.readable? - assert a2.visible? + aa1 = Redmine::Export::PDF::RDMPdfEncoding::attach(Attachment.all, "Testfile.PNG", "UTF-8") + assert_not_nil aa1 + assert_equal 17, aa1.id - aa1 = Redmine::Export::PDF::RDMPdfEncoding::attach(Attachment.all, "Testfile.PNG", "UTF-8") - assert_not_nil aa1 - assert_equal 17, aa1.id - aa2 = Redmine::Export::PDF::RDMPdfEncoding::attach(Attachment.all, "test#{str2}.png", encoding) - assert_not_nil aa2 - assert_equal 19, aa2.id + aa2 = Redmine::Export::PDF::RDMPdfEncoding::attach(Attachment.all, "test#{str2}.png", encoding) + assert_not_nil aa2 + assert_equal 19, aa2.id - User.current = nil - assert a1.readable? - assert (! a1.visible?) - assert a2.readable? - assert (! a2.visible?) + User.current = nil + assert a1.readable? + assert (! a1.visible?) + assert a2.readable? + assert (! a2.visible?) + aa1 = Redmine::Export::PDF::RDMPdfEncoding::attach(Attachment.all, "Testfile.PNG", "UTF-8") + assert_equal nil, aa1 + aa2 = Redmine::Export::PDF::RDMPdfEncoding::attach(Attachment.all, "test#{str2}.png", encoding) + assert_equal nil, aa2 - aa1 = Redmine::Export::PDF::RDMPdfEncoding::attach(Attachment.all, "Testfile.PNG", "UTF-8") - assert_equal nil, aa1 - aa2 = Redmine::Export::PDF::RDMPdfEncoding::attach(Attachment.all, "test#{str2}.png", encoding) - assert_equal nil, aa2 - - set_tmp_attachments_directory + set_tmp_attachments_directory + end end end diff --git a/test/unit/lib/redmine/hook_test.rb b/test/unit/lib/redmine/hook_test.rb index 1352d251e..af9ca9ded 100644 --- a/test/unit/lib/redmine/hook_test.rb +++ b/test/unit/lib/redmine/hook_test.rb @@ -66,6 +66,7 @@ class Redmine::Hook::ManagerTest < ActionView::TestCase def setup @hook_module = Redmine::Hook + @hook_module.clear_listeners end def teardown diff --git a/test/unit/lib/redmine/i18n_test.rb b/test/unit/lib/redmine/i18n_test.rb index 6d3561486..a267fd7b9 100644 --- a/test/unit/lib/redmine/i18n_test.rb +++ b/test/unit/lib/redmine/i18n_test.rb @@ -32,47 +32,50 @@ class Redmine::I18nTest < ActiveSupport::TestCase def test_date_format_default set_language_if_valid 'en' today = Date.today - Setting.date_format = '' - assert_equal I18n.l(today), format_date(today) + with_settings :date_format => '' do + assert_equal I18n.l(today), format_date(today) + end end def test_date_format set_language_if_valid 'en' today = Date.today - Setting.date_format = '%d %m %Y' - assert_equal today.strftime('%d %m %Y'), format_date(today) + with_settings :date_format => '%d %m %Y' do + assert_equal today.strftime('%d %m %Y'), format_date(today) + end end def test_date_format_default_with_user_locale set_language_if_valid 'es' today = now = Time.parse('2011-02-20 14:00:00') - Setting.date_format = '%d %B %Y' - User.current.language = 'fr' - s1 = "20 f\xc3\xa9vrier 2011" - s1.force_encoding("UTF-8") if s1.respond_to?(:force_encoding) - assert_equal s1, format_date(today) - User.current.language = nil - assert_equal '20 Febrero 2011', format_date(today) + with_settings :date_format => '%d %B %Y' do + User.current.language = 'fr' + s1 = "20 f\xc3\xa9vrier 2011".force_encoding("UTF-8") + assert_equal s1, format_date(today) + User.current.language = nil + assert_equal '20 Febrero 2011', format_date(today) + end end def test_date_and_time_for_each_language - Setting.date_format = '' - valid_languages.each do |lang| - set_language_if_valid lang - assert_nothing_raised "#{lang} failure" do - format_date(Date.today) - format_time(Time.now) - format_time(Time.now, false) - assert_not_equal 'default', ::I18n.l(Date.today, :format => :default), - "date.formats.default missing in #{lang}" - assert_not_equal 'time', ::I18n.l(Time.now, :format => :time), - "time.formats.time missing in #{lang}" + with_settings :date_format => '' do + valid_languages.each do |lang| + set_language_if_valid lang + assert_nothing_raised "#{lang} failure" do + format_date(Date.today) + format_time(Time.now) + format_time(Time.now, false) + assert_not_equal 'default', ::I18n.l(Date.today, :format => :default), + "date.formats.default missing in #{lang}" + assert_not_equal 'time', ::I18n.l(Time.now, :format => :time), + "time.formats.time missing in #{lang}" + end + assert l('date.day_names').is_a?(Array) + assert_equal 7, l('date.day_names').size + + assert l('date.month_names').is_a?(Array) + assert_equal 13, l('date.month_names').size end - assert l('date.day_names').is_a?(Array) - assert_equal 7, l('date.day_names').size - - assert l('date.month_names').is_a?(Array) - assert_equal 13, l('date.month_names').size end end @@ -134,10 +137,10 @@ class Redmine::I18nTest < ActiveSupport::TestCase def test_utc_time_format set_language_if_valid 'en' now = Time.now - Setting.date_format = '%d %m %Y' - Setting.time_format = '%H %M' - assert_equal now.strftime('%d %m %Y %H %M'), format_time(now.utc) - assert_equal now.strftime('%H %M'), format_time(now.utc, false) + with_settings :date_format => '%d %m %Y', :time_format => '%H %M' do + assert_equal now.strftime('%d %m %Y %H %M'), format_time(now.utc) + assert_equal now.strftime('%H %M'), format_time(now.utc, false) + end end def test_number_to_human_size_for_each_language @@ -175,8 +178,7 @@ class Redmine::I18nTest < ActiveSupport::TestCase set_language_if_valid 'bs' assert_equal "KM -1000,20", number_to_currency(-1000.2) set_language_if_valid 'de' - euro_sign = "\xe2\x82\xac" - euro_sign.force_encoding('UTF-8') if euro_sign.respond_to?(:force_encoding) + euro_sign = "\xe2\x82\xac".force_encoding('UTF-8') assert_equal "-1000,20 #{euro_sign}", number_to_currency(-1000.2) end @@ -193,8 +195,7 @@ class Redmine::I18nTest < ActiveSupport::TestCase assert_nil options.detect {|option| option.size != 2} assert_nil options.detect {|option| !option.first.is_a?(String) || !option.last.is_a?(String)} assert_include ["English", "en"], options - ja = "Japanese (\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e)" - ja.force_encoding('UTF-8') if ja.respond_to?(:force_encoding) + ja = "Japanese (\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e)".force_encoding('UTF-8') assert_include [ja, "ja"], options end @@ -238,30 +239,21 @@ class Redmine::I18nTest < ActiveSupport::TestCase def test_utf8 set_language_if_valid 'ja' - str_ja_yes = "\xe3\x81\xaf\xe3\x81\x84" + str_ja_yes = "\xe3\x81\xaf\xe3\x81\x84".force_encoding('UTF-8') i18n_ja_yes = l(:general_text_Yes) - if str_ja_yes.respond_to?(:force_encoding) - str_ja_yes.force_encoding('UTF-8') - assert_equal "UTF-8", i18n_ja_yes.encoding.to_s - end assert_equal str_ja_yes, i18n_ja_yes + assert_equal "UTF-8", i18n_ja_yes.encoding.to_s end def test_traditional_chinese_locale set_language_if_valid 'zh-TW' - str_tw = "Traditional Chinese (\xe7\xb9\x81\xe9\xab\x94\xe4\xb8\xad\xe6\x96\x87)" - if str_tw.respond_to?(:force_encoding) - str_tw.force_encoding('UTF-8') - end + str_tw = "Traditional Chinese (\xe7\xb9\x81\xe9\xab\x94\xe4\xb8\xad\xe6\x96\x87)".force_encoding('UTF-8') assert_equal str_tw, l(:general_lang_name) end def test_french_locale set_language_if_valid 'fr' - str_fr = "Fran\xc3\xa7ais" - if str_fr.respond_to?(:force_encoding) - str_fr.force_encoding('UTF-8') - end + str_fr = "Fran\xc3\xa7ais".force_encoding('UTF-8') assert_equal str_fr, l(:general_lang_name) end end diff --git a/test/unit/lib/redmine/scm/adapters/bazaar_adapter_test.rb b/test/unit/lib/redmine/scm/adapters/bazaar_adapter_test.rb index a4699ef4d..272b7ba13 100644 --- a/test/unit/lib/redmine/scm/adapters/bazaar_adapter_test.rb +++ b/test/unit/lib/redmine/scm/adapters/bazaar_adapter_test.rb @@ -16,210 +16,203 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. require File.expand_path('../../../../../../test_helper', __FILE__) -begin - require 'mocha/setup' - - class BazaarAdapterTest < ActiveSupport::TestCase - REPOSITORY_PATH = Rails.root.join('tmp/test/bazaar_repository').to_s - REPOSITORY_PATH.gsub!(/\/+/, '/') - - if File.directory?(REPOSITORY_PATH) - def setup - @adapter = Redmine::Scm::Adapters::BazaarAdapter.new( - File.join(REPOSITORY_PATH, "trunk") - ) - end - def test_scm_version - to_test = { "Bazaar (bzr) 2.1.2\n" => [2,1,2], - "2.1.1\n1.7\n1.8" => [2,1,1], - "2.0.1\r\n1.8.1\r\n1.9.1" => [2,0,1]} - to_test.each do |s, v| - test_scm_version_for(s, v) - end - end +class BazaarAdapterTest < ActiveSupport::TestCase + REPOSITORY_PATH = Rails.root.join('tmp/test/bazaar_repository').to_s + REPOSITORY_PATH.gsub!(/\/+/, '/') - def test_cat - cat = @adapter.cat('directory/document.txt') - assert cat =~ /Write the contents of a file as of a given revision to standard output/ - end + if File.directory?(REPOSITORY_PATH) + def setup + @adapter = Redmine::Scm::Adapters::BazaarAdapter.new( + File.join(REPOSITORY_PATH, "trunk") + ) + end - def test_cat_path_invalid - assert_nil @adapter.cat('invalid') + def test_scm_version + to_test = { "Bazaar (bzr) 2.1.2\n" => [2,1,2], + "2.1.1\n1.7\n1.8" => [2,1,1], + "2.0.1\r\n1.8.1\r\n1.9.1" => [2,0,1]} + to_test.each do |s, v| + test_scm_version_for(s, v) end + end - def test_cat_revision_invalid - assert_nil @adapter.cat('doc-mkdir.txt', '12345678') - end + def test_cat + cat = @adapter.cat('directory/document.txt') + assert cat =~ /Write the contents of a file as of a given revision to standard output/ + end - def test_diff - diff1 = @adapter.diff('doc-mkdir.txt', 3, 2) - assert_equal 21, diff1.size - buf = diff1[14].gsub(/\r\n|\r|\n/, "") - assert_equal "-Display more information.", buf - end + def test_cat_path_invalid + assert_nil @adapter.cat('invalid') + end - def test_diff_path_invalid - assert_equal [], @adapter.diff('invalid', 1) - end + def test_cat_revision_invalid + assert_nil @adapter.cat('doc-mkdir.txt', '12345678') + end - def test_diff_revision_invalid - assert_equal [], @adapter.diff(nil, 12345678) - assert_equal [], @adapter.diff(nil, 12345678, 87654321) - end + def test_diff + diff1 = @adapter.diff('doc-mkdir.txt', 3, 2) + assert_equal 21, diff1.size + buf = diff1[14].gsub(/\r\n|\r|\n/, "") + assert_equal "-Display more information.", buf + end - def test_annotate - annotate = @adapter.annotate('doc-mkdir.txt') - assert_equal 17, annotate.lines.size - assert_equal '1', annotate.revisions[0].identifier - assert_equal 'jsmith@', annotate.revisions[0].author - assert_equal 'mkdir', annotate.lines[0] - end + def test_diff_path_invalid + assert_equal [], @adapter.diff('invalid', 1) + end - def test_annotate_path_invalid - assert_nil @adapter.annotate('invalid') - end + def test_diff_revision_invalid + assert_equal [], @adapter.diff(nil, 12345678) + assert_equal [], @adapter.diff(nil, 12345678, 87654321) + end - def test_annotate_revision_invalid - assert_nil @adapter.annotate('doc-mkdir.txt', '12345678') - end + def test_annotate + annotate = @adapter.annotate('doc-mkdir.txt') + assert_equal 17, annotate.lines.size + assert_equal '1', annotate.revisions[0].identifier + assert_equal 'jsmith@', annotate.revisions[0].author + assert_equal 'mkdir', annotate.lines[0] + end - def test_branch_conf_path - p = "c:\\test\\test\\" - bcp = Redmine::Scm::Adapters::BazaarAdapter.branch_conf_path(p) - assert_equal File.join("c:\\test\\test", ".bzr", "branch", "branch.conf"), bcp - p = "c:\\test\\test\\.bzr" - bcp = Redmine::Scm::Adapters::BazaarAdapter.branch_conf_path(p) - assert_equal File.join("c:\\test\\test", ".bzr", "branch", "branch.conf"), bcp - p = "c:\\test\\test\\.bzr\\" - bcp = Redmine::Scm::Adapters::BazaarAdapter.branch_conf_path(p) - assert_equal File.join("c:\\test\\test", ".bzr", "branch", "branch.conf"), bcp - p = "c:\\test\\test" - bcp = Redmine::Scm::Adapters::BazaarAdapter.branch_conf_path(p) - assert_equal File.join("c:\\test\\test", ".bzr", "branch", "branch.conf"), bcp - p = "\\\\server\\test\\test\\" - bcp = Redmine::Scm::Adapters::BazaarAdapter.branch_conf_path(p) - assert_equal File.join("\\\\server\\test\\test", ".bzr", "branch", "branch.conf"), bcp - end + def test_annotate_path_invalid + assert_nil @adapter.annotate('invalid') + end - def test_append_revisions_only_true - assert_equal true, @adapter.append_revisions_only - end + def test_annotate_revision_invalid + assert_nil @adapter.annotate('doc-mkdir.txt', '12345678') + end - def test_append_revisions_only_false - adpt = Redmine::Scm::Adapters::BazaarAdapter.new( - File.join(REPOSITORY_PATH, "empty-branch") - ) - assert_equal false, adpt.append_revisions_only - end + def test_branch_conf_path + p = "c:\\test\\test\\" + bcp = Redmine::Scm::Adapters::BazaarAdapter.branch_conf_path(p) + assert_equal File.join("c:\\test\\test", ".bzr", "branch", "branch.conf"), bcp + p = "c:\\test\\test\\.bzr" + bcp = Redmine::Scm::Adapters::BazaarAdapter.branch_conf_path(p) + assert_equal File.join("c:\\test\\test", ".bzr", "branch", "branch.conf"), bcp + p = "c:\\test\\test\\.bzr\\" + bcp = Redmine::Scm::Adapters::BazaarAdapter.branch_conf_path(p) + assert_equal File.join("c:\\test\\test", ".bzr", "branch", "branch.conf"), bcp + p = "c:\\test\\test" + bcp = Redmine::Scm::Adapters::BazaarAdapter.branch_conf_path(p) + assert_equal File.join("c:\\test\\test", ".bzr", "branch", "branch.conf"), bcp + p = "\\\\server\\test\\test\\" + bcp = Redmine::Scm::Adapters::BazaarAdapter.branch_conf_path(p) + assert_equal File.join("\\\\server\\test\\test", ".bzr", "branch", "branch.conf"), bcp + end - def test_append_revisions_only_shared_repo - adpt = Redmine::Scm::Adapters::BazaarAdapter.new( - REPOSITORY_PATH - ) - assert_equal false, adpt.append_revisions_only - end + def test_append_revisions_only_true + assert_equal true, @adapter.append_revisions_only + end - def test_info_not_nil - assert_not_nil @adapter.info - end + def test_append_revisions_only_false + adpt = Redmine::Scm::Adapters::BazaarAdapter.new( + File.join(REPOSITORY_PATH, "empty-branch") + ) + assert_equal false, adpt.append_revisions_only + end - def test_info_nil - adpt = Redmine::Scm::Adapters::BazaarAdapter.new( - "/invalid/invalid/" - ) - assert_nil adpt.info - end + def test_append_revisions_only_shared_repo + adpt = Redmine::Scm::Adapters::BazaarAdapter.new( + REPOSITORY_PATH + ) + assert_equal false, adpt.append_revisions_only + end - def test_info - info = @adapter.info - assert_equal 4, info.lastrev.identifier.to_i - end + def test_info_not_nil + assert_not_nil @adapter.info + end - def test_info_emtpy - adpt = Redmine::Scm::Adapters::BazaarAdapter.new( - File.join(REPOSITORY_PATH, "empty-branch") - ) - assert_equal 0, adpt.info.lastrev.identifier.to_i - end + def test_info_nil + adpt = Redmine::Scm::Adapters::BazaarAdapter.new( + "/invalid/invalid/" + ) + assert_nil adpt.info + end - def test_entries_path_invalid - assert_equal [], @adapter.entries('invalid') - end + def test_info + info = @adapter.info + assert_equal 4, info.lastrev.identifier.to_i + end - def test_entries_revision_invalid - assert_nil @adapter.entries(nil, 12345678) - end + def test_info_emtpy + adpt = Redmine::Scm::Adapters::BazaarAdapter.new( + File.join(REPOSITORY_PATH, "empty-branch") + ) + assert_equal 0, adpt.info.lastrev.identifier.to_i + end - def test_revisions - revisions = @adapter.revisions(nil, 4, 2) - assert_equal 3, revisions.size - assert_equal 2, revisions[2].identifier - assert_equal 'jsmith@foo.bar-20071203175224-v0eog5d5wrgdrshg', revisions[2].scmid - assert_equal 4, revisions[0].identifier - assert_equal 'jsmith@foo.bar-20071203175422-t40bf8li5zz0c4cg', revisions[0].scmid - assert_equal 2, revisions[0].paths.size - assert_equal 'D', revisions[0].paths[0][:action] - assert_equal '/doc-deleted.txt', revisions[0].paths[0][:path] - assert_equal 'docdeleted.txt-20071203175320-iwwj561ojuubs3gt-1', revisions[0].paths[0][:revision] - assert_equal 'M', revisions[0].paths[1][:action] - assert_equal '/directory/doc-ls.txt', revisions[0].paths[1][:path] - assert_equal 'docls.txt-20071203175005-a3hyc3mn0shl7cgu-1', revisions[0].paths[1][:revision] - end + def test_entries_path_invalid + assert_equal [], @adapter.entries('invalid') + end - def test_revisions_path_invalid - assert_nil @adapter.revisions('invalid') - end + def test_entries_revision_invalid + assert_nil @adapter.entries(nil, 12345678) + end - def test_revisions_revision_invalid - assert_nil @adapter.revisions(nil, 12345678) - assert_nil @adapter.revisions(nil, 12345678, 87654321) - end + def test_revisions + revisions = @adapter.revisions(nil, 4, 2) + assert_equal 3, revisions.size + assert_equal 2, revisions[2].identifier + assert_equal 'jsmith@foo.bar-20071203175224-v0eog5d5wrgdrshg', revisions[2].scmid + assert_equal 4, revisions[0].identifier + assert_equal 'jsmith@foo.bar-20071203175422-t40bf8li5zz0c4cg', revisions[0].scmid + assert_equal 2, revisions[0].paths.size + assert_equal 'D', revisions[0].paths[0][:action] + assert_equal '/doc-deleted.txt', revisions[0].paths[0][:path] + assert_equal 'docdeleted.txt-20071203175320-iwwj561ojuubs3gt-1', revisions[0].paths[0][:revision] + assert_equal 'M', revisions[0].paths[1][:action] + assert_equal '/directory/doc-ls.txt', revisions[0].paths[1][:path] + assert_equal 'docls.txt-20071203175005-a3hyc3mn0shl7cgu-1', revisions[0].paths[1][:revision] + end - def test_entry - entry = @adapter.entry() - assert_equal "", entry.path - assert_equal "dir", entry.kind - entry = @adapter.entry('') - assert_equal "", entry.path + def test_revisions_path_invalid + assert_nil @adapter.revisions('invalid') + end + + def test_revisions_revision_invalid + assert_nil @adapter.revisions(nil, 12345678) + assert_nil @adapter.revisions(nil, 12345678, 87654321) + end + + def test_entry + entry = @adapter.entry() + assert_equal "", entry.path + assert_equal "dir", entry.kind + entry = @adapter.entry('') + assert_equal "", entry.path + assert_equal "dir", entry.kind + assert_nil @adapter.entry('invalid') + assert_nil @adapter.entry('/invalid') + assert_nil @adapter.entry('/invalid/') + assert_nil @adapter.entry('invalid/invalid') + assert_nil @adapter.entry('invalid/invalid/') + assert_nil @adapter.entry('/invalid/invalid') + assert_nil @adapter.entry('/invalid/invalid/') + ["doc-ls.txt", "/doc-ls.txt"].each do |path| + entry = @adapter.entry(path, 2) + assert_equal "doc-ls.txt", entry.path + assert_equal "file", entry.kind + end + ["directory", "/directory", "/directory/"].each do |path| + entry = @adapter.entry(path, 2) + assert_equal "directory", entry.path assert_equal "dir", entry.kind - assert_nil @adapter.entry('invalid') - assert_nil @adapter.entry('/invalid') - assert_nil @adapter.entry('/invalid/') - assert_nil @adapter.entry('invalid/invalid') - assert_nil @adapter.entry('invalid/invalid/') - assert_nil @adapter.entry('/invalid/invalid') - assert_nil @adapter.entry('/invalid/invalid/') - ["doc-ls.txt", "/doc-ls.txt"].each do |path| - entry = @adapter.entry(path, 2) - assert_equal "doc-ls.txt", entry.path - assert_equal "file", entry.kind - end - ["directory", "/directory", "/directory/"].each do |path| - entry = @adapter.entry(path, 2) - assert_equal "directory", entry.path - assert_equal "dir", entry.kind - end - ["directory/document.txt", "/directory/document.txt"].each do |path| - entry = @adapter.entry(path, 2) - assert_equal "directory/document.txt", entry.path - assert_equal "file", entry.kind - end end + ["directory/document.txt", "/directory/document.txt"].each do |path| + entry = @adapter.entry(path, 2) + assert_equal "directory/document.txt", entry.path + assert_equal "file", entry.kind + end + end - private + private - def test_scm_version_for(scm_command_version, version) - @adapter.class.expects(:scm_version_from_command_line).returns(scm_command_version) - assert_equal version, @adapter.class.scm_command_version - end - else - puts "Bazaar test repository NOT FOUND. Skipping unit tests !!!" - def test_fake; assert true end + def test_scm_version_for(scm_command_version, version) + @adapter.class.expects(:scm_version_from_command_line).returns(scm_command_version) + assert_equal version, @adapter.class.scm_command_version end - end -rescue LoadError - class BazaarMochaFake < ActiveSupport::TestCase - def test_fake; assert(false, "Requires mocha to run those tests") end + else + puts "Bazaar test repository NOT FOUND. Skipping unit tests !!!" + def test_fake; assert true end end end diff --git a/test/unit/lib/redmine/scm/adapters/cvs_adapter_test.rb b/test/unit/lib/redmine/scm/adapters/cvs_adapter_test.rb index cf5ab791c..504a3ad78 100644 --- a/test/unit/lib/redmine/scm/adapters/cvs_adapter_test.rb +++ b/test/unit/lib/redmine/scm/adapters/cvs_adapter_test.rb @@ -16,100 +16,91 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. require File.expand_path('../../../../../../test_helper', __FILE__) -begin - require 'mocha/setup' - class CvsAdapterTest < ActiveSupport::TestCase - REPOSITORY_PATH = Rails.root.join('tmp/test/cvs_repository').to_s - REPOSITORY_PATH.gsub!(/\//, "\\") if Redmine::Platform.mswin? - MODULE_NAME = 'test' +class CvsAdapterTest < ActiveSupport::TestCase + REPOSITORY_PATH = Rails.root.join('tmp/test/cvs_repository').to_s + REPOSITORY_PATH.gsub!(/\//, "\\") if Redmine::Platform.mswin? + MODULE_NAME = 'test' - if File.directory?(REPOSITORY_PATH) - def setup - @adapter = Redmine::Scm::Adapters::CvsAdapter.new(MODULE_NAME, REPOSITORY_PATH) - end + if File.directory?(REPOSITORY_PATH) + def setup + @adapter = Redmine::Scm::Adapters::CvsAdapter.new(MODULE_NAME, REPOSITORY_PATH) + end - def test_scm_version - to_test = { "\nConcurrent Versions System (CVS) 1.12.13 (client/server)\n" => [1,12,13], - "\r\n1.12.12\r\n1.12.11" => [1,12,12], - "1.12.11\r\n1.12.10\r\n" => [1,12,11]} - to_test.each do |s, v| - test_scm_version_for(s, v) - end + def test_scm_version + to_test = { "\nConcurrent Versions System (CVS) 1.12.13 (client/server)\n" => [1,12,13], + "\r\n1.12.12\r\n1.12.11" => [1,12,12], + "1.12.11\r\n1.12.10\r\n" => [1,12,11]} + to_test.each do |s, v| + test_scm_version_for(s, v) end + end - def test_revisions_all - cnt = 0 - @adapter.revisions('', nil, nil, :log_encoding => 'UTF-8') do |revision| - cnt += 1 - end - assert_equal 16, cnt + def test_revisions_all + cnt = 0 + @adapter.revisions('', nil, nil, :log_encoding => 'UTF-8') do |revision| + cnt += 1 end + assert_equal 16, cnt + end - def test_revisions_from_rev3 - rev3_committed_on = Time.gm(2007, 12, 13, 16, 27, 22) - cnt = 0 - @adapter.revisions('', rev3_committed_on, nil, :log_encoding => 'UTF-8') do |revision| - cnt += 1 - end - assert_equal 4, cnt + def test_revisions_from_rev3 + rev3_committed_on = Time.gm(2007, 12, 13, 16, 27, 22) + cnt = 0 + @adapter.revisions('', rev3_committed_on, nil, :log_encoding => 'UTF-8') do |revision| + cnt += 1 end + assert_equal 4, cnt + end - def test_entries_rev3 - rev3_committed_on = Time.gm(2007, 12, 13, 16, 27, 22) - entries = @adapter.entries('sources', rev3_committed_on) - assert_equal 2, entries.size - assert_equal entries[0].name, "watchers_controller.rb" - assert_equal entries[0].lastrev.time, Time.gm(2007, 12, 13, 16, 27, 22) - end + def test_entries_rev3 + rev3_committed_on = Time.gm(2007, 12, 13, 16, 27, 22) + entries = @adapter.entries('sources', rev3_committed_on) + assert_equal 2, entries.size + assert_equal entries[0].name, "watchers_controller.rb" + assert_equal entries[0].lastrev.time, Time.gm(2007, 12, 13, 16, 27, 22) + end - def test_path_encoding_default_utf8 - adpt1 = Redmine::Scm::Adapters::CvsAdapter.new( - MODULE_NAME, - REPOSITORY_PATH - ) - assert_equal "UTF-8", adpt1.path_encoding - adpt2 = Redmine::Scm::Adapters::CvsAdapter.new( - MODULE_NAME, - REPOSITORY_PATH, - nil, - nil, - "" - ) - assert_equal "UTF-8", adpt2.path_encoding - end + def test_path_encoding_default_utf8 + adpt1 = Redmine::Scm::Adapters::CvsAdapter.new( + MODULE_NAME, + REPOSITORY_PATH + ) + assert_equal "UTF-8", adpt1.path_encoding + adpt2 = Redmine::Scm::Adapters::CvsAdapter.new( + MODULE_NAME, + REPOSITORY_PATH, + nil, + nil, + "" + ) + assert_equal "UTF-8", adpt2.path_encoding + end - def test_root_url_path - to_test = { - ':pserver:cvs_user:cvs_password@123.456.789.123:9876/repo' => '/repo', - ':pserver:cvs_user:cvs_password@123.456.789.123/repo' => '/repo', - ':pserver:cvs_user:cvs_password@cvs_server:/repo' => '/repo', - ':pserver:cvs_user:cvs_password@cvs_server:9876/repo' => '/repo', - ':pserver:cvs_user:cvs_password@cvs_server/repo' => '/repo', - ':pserver:cvs_user:cvs_password@cvs_server/path/repo' => '/path/repo', - ':ext:cvsservername:/path' => '/path' - } + def test_root_url_path + to_test = { + ':pserver:cvs_user:cvs_password@123.456.789.123:9876/repo' => '/repo', + ':pserver:cvs_user:cvs_password@123.456.789.123/repo' => '/repo', + ':pserver:cvs_user:cvs_password@cvs_server:/repo' => '/repo', + ':pserver:cvs_user:cvs_password@cvs_server:9876/repo' => '/repo', + ':pserver:cvs_user:cvs_password@cvs_server/repo' => '/repo', + ':pserver:cvs_user:cvs_password@cvs_server/path/repo' => '/path/repo', + ':ext:cvsservername:/path' => '/path' + } - to_test.each do |string, expected| - assert_equal expected, Redmine::Scm::Adapters::CvsAdapter.new('foo', string).send(:root_url_path), "#{string} failed" - end + to_test.each do |string, expected| + assert_equal expected, Redmine::Scm::Adapters::CvsAdapter.new('foo', string).send(:root_url_path), "#{string} failed" end + end - private + private - def test_scm_version_for(scm_command_version, version) - @adapter.class.expects(:scm_version_from_command_line).returns(scm_command_version) - assert_equal version, @adapter.class.scm_command_version - end - else - puts "Cvs test repository NOT FOUND. Skipping unit tests !!!" - def test_fake; assert true end + def test_scm_version_for(scm_command_version, version) + @adapter.class.expects(:scm_version_from_command_line).returns(scm_command_version) + assert_equal version, @adapter.class.scm_command_version end - end - -rescue LoadError - class CvsMochaFake < ActiveSupport::TestCase - def test_fake; assert(false, "Requires mocha to run those tests") end + else + puts "Cvs test repository NOT FOUND. Skipping unit tests !!!" + def test_fake; assert true end end end - diff --git a/test/unit/lib/redmine/scm/adapters/darcs_adapter_test.rb b/test/unit/lib/redmine/scm/adapters/darcs_adapter_test.rb index b6f877521..e28c84946 100644 --- a/test/unit/lib/redmine/scm/adapters/darcs_adapter_test.rb +++ b/test/unit/lib/redmine/scm/adapters/darcs_adapter_test.rb @@ -16,54 +16,45 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. require File.expand_path('../../../../../../test_helper', __FILE__) -begin - require 'mocha/setup' - class DarcsAdapterTest < ActiveSupport::TestCase - REPOSITORY_PATH = Rails.root.join('tmp/test/darcs_repository').to_s +class DarcsAdapterTest < ActiveSupport::TestCase + REPOSITORY_PATH = Rails.root.join('tmp/test/darcs_repository').to_s - if File.directory?(REPOSITORY_PATH) - def setup - @adapter = Redmine::Scm::Adapters::DarcsAdapter.new(REPOSITORY_PATH) - end - - def test_darcsversion - to_test = { "1.0.9 (release)\n" => [1,0,9] , - "2.2.0 (release)\n" => [2,2,0] } - to_test.each do |s, v| - test_darcsversion_for(s, v) - end - end + if File.directory?(REPOSITORY_PATH) + def setup + @adapter = Redmine::Scm::Adapters::DarcsAdapter.new(REPOSITORY_PATH) + end - def test_revisions - id1 = '20080308225258-98289-761f654d669045eabee90b91b53a21ce5593cadf.gz' - revs = @adapter.revisions('', nil, nil, {:with_path => true}) - assert_equal 6, revs.size - assert_equal id1, revs[5].scmid - paths = revs[5].paths - assert_equal 5, paths.size - assert_equal 'A', paths[0][:action] - assert_equal '/README', paths[0][:path] - assert_equal 'A', paths[1][:action] - assert_equal '/images', paths[1][:path] + def test_darcsversion + to_test = { "1.0.9 (release)\n" => [1,0,9] , + "2.2.0 (release)\n" => [2,2,0] } + to_test.each do |s, v| + test_darcsversion_for(s, v) end + end - private + def test_revisions + id1 = '20080308225258-98289-761f654d669045eabee90b91b53a21ce5593cadf.gz' + revs = @adapter.revisions('', nil, nil, {:with_path => true}) + assert_equal 6, revs.size + assert_equal id1, revs[5].scmid + paths = revs[5].paths + assert_equal 5, paths.size + assert_equal 'A', paths[0][:action] + assert_equal '/README', paths[0][:path] + assert_equal 'A', paths[1][:action] + assert_equal '/images', paths[1][:path] + end - def test_darcsversion_for(darcsversion, version) - @adapter.class.expects(:darcs_binary_version_from_command_line).returns(darcsversion) - assert_equal version, @adapter.class.darcs_binary_version - end + private - else - puts "Darcs test repository NOT FOUND. Skipping unit tests !!!" - def test_fake; assert true end + def test_darcsversion_for(darcsversion, version) + @adapter.class.expects(:darcs_binary_version_from_command_line).returns(darcsversion) + assert_equal version, @adapter.class.darcs_binary_version end - end -rescue LoadError - class DarcsMochaFake < ActiveSupport::TestCase - def test_fake; assert(false, "Requires mocha to run those tests") end + else + puts "Darcs test repository NOT FOUND. Skipping unit tests !!!" + def test_fake; assert true end end end - diff --git a/test/unit/lib/redmine/scm/adapters/git_adapter_test.rb b/test/unit/lib/redmine/scm/adapters/git_adapter_test.rb index a140d25dc..7342b2244 100644 --- a/test/unit/lib/redmine/scm/adapters/git_adapter_test.rb +++ b/test/unit/lib/redmine/scm/adapters/git_adapter_test.rb @@ -16,594 +16,582 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. require File.expand_path('../../../../../../test_helper', __FILE__) -begin - require 'mocha/setup' - - class GitAdapterTest < ActiveSupport::TestCase - REPOSITORY_PATH = Rails.root.join('tmp/test/git_repository').to_s - - FELIX_HEX = "Felix Sch\xC3\xA4fer" - CHAR_1_HEX = "\xc3\x9c" - - ## Git, Mercurial and CVS path encodings are binary. - ## Subversion supports URL encoding for path. - ## Redmine Mercurial adapter and extension use URL encoding. - ## Git accepts only binary path in command line parameter. - ## So, there is no way to use binary command line parameter in JRuby. - JRUBY_SKIP = (RUBY_PLATFORM == 'java') - JRUBY_SKIP_STR = "TODO: This test fails in JRuby" - - if File.directory?(REPOSITORY_PATH) - ## Ruby uses ANSI api to fork a process on Windows. - ## Japanese Shift_JIS and Traditional Chinese Big5 have 0x5c(backslash) problem - ## and these are incompatible with ASCII. - ## Git for Windows (msysGit) changed internal API from ANSI to Unicode in 1.7.10 - ## http://code.google.com/p/msysgit/issues/detail?id=80 - ## So, Latin-1 path tests fail on Japanese Windows - WINDOWS_PASS = (Redmine::Platform.mswin? && - Redmine::Scm::Adapters::GitAdapter.client_version_above?([1, 7, 10])) - WINDOWS_SKIP_STR = "TODO: This test fails in Git for Windows above 1.7.10" - - def setup - adapter_class = Redmine::Scm::Adapters::GitAdapter - assert adapter_class - assert adapter_class.client_command - assert_equal true, adapter_class.client_available - assert_equal true, adapter_class.client_version_above?([1]) - assert_equal true, adapter_class.client_version_above?([1, 0]) - - @adapter = Redmine::Scm::Adapters::GitAdapter.new( - REPOSITORY_PATH, - nil, - nil, - nil, - 'ISO-8859-1' - ) - assert @adapter - @char_1 = CHAR_1_HEX.dup - @str_felix_hex = FELIX_HEX.dup - if @char_1.respond_to?(:force_encoding) - @char_1.force_encoding('UTF-8') - @str_felix_hex.force_encoding('ASCII-8BIT') - end - end - def test_scm_version - to_test = { "git version 1.7.3.4\n" => [1,7,3,4], - "1.6.1\n1.7\n1.8" => [1,6,1], - "1.6.2\r\n1.8.1\r\n1.9.1" => [1,6,2]} - to_test.each do |s, v| - test_scm_version_for(s, v) - end - end +class GitAdapterTest < ActiveSupport::TestCase + REPOSITORY_PATH = Rails.root.join('tmp/test/git_repository').to_s + + FELIX_HEX = "Felix Sch\xC3\xA4fer" + CHAR_1_HEX = "\xc3\x9c" + + ## Git, Mercurial and CVS path encodings are binary. + ## Subversion supports URL encoding for path. + ## Redmine Mercurial adapter and extension use URL encoding. + ## Git accepts only binary path in command line parameter. + ## So, there is no way to use binary command line parameter in JRuby. + JRUBY_SKIP = (RUBY_PLATFORM == 'java') + JRUBY_SKIP_STR = "TODO: This test fails in JRuby" + + if File.directory?(REPOSITORY_PATH) + ## Ruby uses ANSI api to fork a process on Windows. + ## Japanese Shift_JIS and Traditional Chinese Big5 have 0x5c(backslash) problem + ## and these are incompatible with ASCII. + ## Git for Windows (msysGit) changed internal API from ANSI to Unicode in 1.7.10 + ## http://code.google.com/p/msysgit/issues/detail?id=80 + ## So, Latin-1 path tests fail on Japanese Windows + WINDOWS_PASS = (Redmine::Platform.mswin? && + Redmine::Scm::Adapters::GitAdapter.client_version_above?([1, 7, 10])) + WINDOWS_SKIP_STR = "TODO: This test fails in Git for Windows above 1.7.10" + + def setup + adapter_class = Redmine::Scm::Adapters::GitAdapter + assert adapter_class + assert adapter_class.client_command + assert_equal true, adapter_class.client_available + assert_equal true, adapter_class.client_version_above?([1]) + assert_equal true, adapter_class.client_version_above?([1, 0]) + + @adapter = Redmine::Scm::Adapters::GitAdapter.new( + REPOSITORY_PATH, + nil, + nil, + nil, + 'ISO-8859-1' + ) + assert @adapter + @char_1 = CHAR_1_HEX.dup.force_encoding('UTF-8') + @str_felix_hex = FELIX_HEX.dup.force_encoding('ASCII-8BIT') + end - def test_branches - brs = [] - @adapter.branches.each do |b| - brs << b - end - assert_equal 6, brs.length - br_issue_8857 = brs[0] - assert_equal 'issue-8857', br_issue_8857.to_s - assert_equal '2a682156a3b6e77a8bf9cd4590e8db757f3c6c78', br_issue_8857.revision - assert_equal br_issue_8857.scmid, br_issue_8857.revision - assert_equal false, br_issue_8857.is_default - br_latin_1_path = brs[1] - assert_equal 'latin-1-path-encoding', br_latin_1_path.to_s - assert_equal '1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127', br_latin_1_path.revision - assert_equal br_latin_1_path.scmid, br_latin_1_path.revision - assert_equal false, br_latin_1_path.is_default - br_master = brs[2] - assert_equal 'master', br_master.to_s - assert_equal '83ca5fd546063a3c7dc2e568ba3355661a9e2b2c', br_master.revision - assert_equal br_master.scmid, br_master.revision - assert_equal false, br_master.is_default - br_master_20120212 = brs[3] - assert_equal 'master-20120212', br_master_20120212.to_s - assert_equal '83ca5fd546063a3c7dc2e568ba3355661a9e2b2c', br_master_20120212.revision - assert_equal br_master_20120212.scmid, br_master_20120212.revision - assert_equal true, br_master_20120212.is_default - br_latin_1 = brs[-2] - assert_equal 'test-latin-1', br_latin_1.to_s - assert_equal '67e7792ce20ccae2e4bb73eed09bb397819c8834', br_latin_1.revision - assert_equal br_latin_1.scmid, br_latin_1.revision - assert_equal false, br_latin_1.is_default - br_test = brs[-1] - assert_equal 'test_branch', br_test.to_s - assert_equal 'fba357b886984ee71185ad2065e65fc0417d9b92', br_test.revision - assert_equal br_test.scmid, br_test.revision - assert_equal false, br_test.is_default + def test_scm_version + to_test = { "git version 1.7.3.4\n" => [1,7,3,4], + "1.6.1\n1.7\n1.8" => [1,6,1], + "1.6.2\r\n1.8.1\r\n1.9.1" => [1,6,2]} + to_test.each do |s, v| + test_scm_version_for(s, v) end + end - def test_default_branch - assert_equal 'master-20120212', @adapter.default_branch - end + def test_branches + brs = [] + @adapter.branches.each do |b| + brs << b + end + assert_equal 6, brs.length + br_issue_8857 = brs[0] + assert_equal 'issue-8857', br_issue_8857.to_s + assert_equal '2a682156a3b6e77a8bf9cd4590e8db757f3c6c78', br_issue_8857.revision + assert_equal br_issue_8857.scmid, br_issue_8857.revision + assert_equal false, br_issue_8857.is_default + br_latin_1_path = brs[1] + assert_equal 'latin-1-path-encoding', br_latin_1_path.to_s + assert_equal '1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127', br_latin_1_path.revision + assert_equal br_latin_1_path.scmid, br_latin_1_path.revision + assert_equal false, br_latin_1_path.is_default + br_master = brs[2] + assert_equal 'master', br_master.to_s + assert_equal '83ca5fd546063a3c7dc2e568ba3355661a9e2b2c', br_master.revision + assert_equal br_master.scmid, br_master.revision + assert_equal false, br_master.is_default + br_master_20120212 = brs[3] + assert_equal 'master-20120212', br_master_20120212.to_s + assert_equal '83ca5fd546063a3c7dc2e568ba3355661a9e2b2c', br_master_20120212.revision + assert_equal br_master_20120212.scmid, br_master_20120212.revision + assert_equal true, br_master_20120212.is_default + br_latin_1 = brs[-2] + assert_equal 'test-latin-1', br_latin_1.to_s + assert_equal '67e7792ce20ccae2e4bb73eed09bb397819c8834', br_latin_1.revision + assert_equal br_latin_1.scmid, br_latin_1.revision + assert_equal false, br_latin_1.is_default + br_test = brs[-1] + assert_equal 'test_branch', br_test.to_s + assert_equal 'fba357b886984ee71185ad2065e65fc0417d9b92', br_test.revision + assert_equal br_test.scmid, br_test.revision + assert_equal false, br_test.is_default + end - def test_tags - assert_equal [ - "tag00.lightweight", - "tag01.annotated", - ], @adapter.tags - end + def test_default_branch + assert_equal 'master-20120212', @adapter.default_branch + end - def test_revisions_master_all - revs1 = [] - @adapter.revisions('', nil, "master",{}) do |rev| - revs1 << rev - end - assert_equal 15, revs1.length - assert_equal '83ca5fd546063a3c7dc2e568ba3355661a9e2b2c', revs1[ 0].identifier - assert_equal '7234cb2750b63f47bff735edc50a1c0a433c2518', revs1[-1].identifier - - revs2 = [] - @adapter.revisions('', nil, "master", - {:reverse => true}) do |rev| - revs2 << rev - end - assert_equal 15, revs2.length - assert_equal '83ca5fd546063a3c7dc2e568ba3355661a9e2b2c', revs2[-1].identifier - assert_equal '7234cb2750b63f47bff735edc50a1c0a433c2518', revs2[ 0].identifier - end + def test_tags + assert_equal [ + "tag00.lightweight", + "tag01.annotated", + ], @adapter.tags + end - def test_revisions_master_merged_rev - revs1 = [] - @adapter.revisions('', - "713f4944648826f558cf548222f813dabe7cbb04", - "master", - {:reverse => true}) do |rev| - revs1 << rev - end - assert_equal 8, revs1.length - assert_equal 'fba357b886984ee71185ad2065e65fc0417d9b92', revs1[ 0].identifier - assert_equal '7e61ac704deecde634b51e59daa8110435dcb3da', revs1[ 1].identifier - # 4a07fe31b is not a child of 713f49446 - assert_equal '4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8', revs1[ 2].identifier - # Merged revision - assert_equal '32ae898b720c2f7eec2723d5bdd558b4cb2d3ddf', revs1[ 3].identifier - assert_equal '83ca5fd546063a3c7dc2e568ba3355661a9e2b2c', revs1[-1].identifier - - revs2 = [] - @adapter.revisions('', - "fba357b886984ee71185ad2065e65fc0417d9b92", - "master", - {:reverse => true}) do |rev| - revs2 << rev - end - assert_equal 7, revs2.length - assert_equal '7e61ac704deecde634b51e59daa8110435dcb3da', revs2[ 0].identifier - # 4a07fe31b is not a child of fba357b8869 - assert_equal '4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8', revs2[ 1].identifier - # Merged revision - assert_equal '32ae898b720c2f7eec2723d5bdd558b4cb2d3ddf', revs2[ 2].identifier - assert_equal '83ca5fd546063a3c7dc2e568ba3355661a9e2b2c', revs2[-1].identifier + def test_revisions_master_all + revs1 = [] + @adapter.revisions('', nil, "master",{}) do |rev| + revs1 << rev end + assert_equal 15, revs1.length + assert_equal '83ca5fd546063a3c7dc2e568ba3355661a9e2b2c', revs1[ 0].identifier + assert_equal '7234cb2750b63f47bff735edc50a1c0a433c2518', revs1[-1].identifier - def test_revisions_branch_latin_1_path_encoding_all - revs1 = [] - @adapter.revisions('', nil, "latin-1-path-encoding",{}) do |rev| - revs1 << rev - end - assert_equal 8, revs1.length - assert_equal '1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127', revs1[ 0].identifier - assert_equal '7234cb2750b63f47bff735edc50a1c0a433c2518', revs1[-1].identifier - - revs2 = [] - @adapter.revisions('', nil, "latin-1-path-encoding", - {:reverse => true}) do |rev| - revs2 << rev - end - assert_equal 8, revs2.length - assert_equal '1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127', revs2[-1].identifier - assert_equal '7234cb2750b63f47bff735edc50a1c0a433c2518', revs2[ 0].identifier + revs2 = [] + @adapter.revisions('', nil, "master", + {:reverse => true}) do |rev| + revs2 << rev end + assert_equal 15, revs2.length + assert_equal '83ca5fd546063a3c7dc2e568ba3355661a9e2b2c', revs2[-1].identifier + assert_equal '7234cb2750b63f47bff735edc50a1c0a433c2518', revs2[ 0].identifier + end - def test_revisions_branch_latin_1_path_encoding_with_rev - revs1 = [] - @adapter.revisions('', - '7234cb2750b63f47bff735edc50a1c0a433c2518', - "latin-1-path-encoding", - {:reverse => true}) do |rev| - revs1 << rev - end - assert_equal 7, revs1.length - assert_equal '899a15dba03a3b350b89c3f537e4bbe02a03cdc9', revs1[ 0].identifier - assert_equal '1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127', revs1[-1].identifier + def test_revisions_master_merged_rev + revs1 = [] + @adapter.revisions('', + "713f4944648826f558cf548222f813dabe7cbb04", + "master", + {:reverse => true}) do |rev| + revs1 << rev + end + assert_equal 8, revs1.length + assert_equal 'fba357b886984ee71185ad2065e65fc0417d9b92', revs1[ 0].identifier + assert_equal '7e61ac704deecde634b51e59daa8110435dcb3da', revs1[ 1].identifier + # 4a07fe31b is not a child of 713f49446 + assert_equal '4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8', revs1[ 2].identifier + # Merged revision + assert_equal '32ae898b720c2f7eec2723d5bdd558b4cb2d3ddf', revs1[ 3].identifier + assert_equal '83ca5fd546063a3c7dc2e568ba3355661a9e2b2c', revs1[-1].identifier + + revs2 = [] + @adapter.revisions('', + "fba357b886984ee71185ad2065e65fc0417d9b92", + "master", + {:reverse => true}) do |rev| + revs2 << rev + end + assert_equal 7, revs2.length + assert_equal '7e61ac704deecde634b51e59daa8110435dcb3da', revs2[ 0].identifier + # 4a07fe31b is not a child of fba357b8869 + assert_equal '4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8', revs2[ 1].identifier + # Merged revision + assert_equal '32ae898b720c2f7eec2723d5bdd558b4cb2d3ddf', revs2[ 2].identifier + assert_equal '83ca5fd546063a3c7dc2e568ba3355661a9e2b2c', revs2[-1].identifier + end - revs2 = [] - @adapter.revisions('', - '57ca437c0acbbcb749821fdf3726a1367056d364', - "latin-1-path-encoding", - {:reverse => true}) do |rev| - revs2 << rev - end - assert_equal 3, revs2.length - assert_equal '4fc55c43bf3d3dc2efb66145365ddc17639ce81e', revs2[ 0].identifier - assert_equal '1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127', revs2[-1].identifier + def test_revisions_branch_latin_1_path_encoding_all + revs1 = [] + @adapter.revisions('', nil, "latin-1-path-encoding",{}) do |rev| + revs1 << rev end + assert_equal 8, revs1.length + assert_equal '1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127', revs1[ 0].identifier + assert_equal '7234cb2750b63f47bff735edc50a1c0a433c2518', revs1[-1].identifier - def test_revisions_invalid_rev - assert_equal [], @adapter.revisions('', '1234abcd', "master") - assert_raise Redmine::Scm::Adapters::CommandFailed do - revs1 = [] - @adapter.revisions('', - '1234abcd', - "master", - {:reverse => true}) do |rev| - revs1 << rev - end - end + revs2 = [] + @adapter.revisions('', nil, "latin-1-path-encoding", + {:reverse => true}) do |rev| + revs2 << rev end + assert_equal 8, revs2.length + assert_equal '1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127', revs2[-1].identifier + assert_equal '7234cb2750b63f47bff735edc50a1c0a433c2518', revs2[ 0].identifier + end - def test_revisions_includes_master_two_revs - revs1 = [] - @adapter.revisions('', nil, nil, - {:reverse => true, - :includes => ['83ca5fd546063a3c7dc2e568ba3355661a9e2b2c'], - :excludes => ['4f26664364207fa8b1af9f8722647ab2d4ac5d43']}) do |rev| - revs1 << rev - end - assert_equal 2, revs1.length - assert_equal 'ed5bb786bbda2dee66a2d50faf51429dbc043a7b', revs1[ 0].identifier - assert_equal '83ca5fd546063a3c7dc2e568ba3355661a9e2b2c', revs1[-1].identifier - end + def test_revisions_branch_latin_1_path_encoding_with_rev + revs1 = [] + @adapter.revisions('', + '7234cb2750b63f47bff735edc50a1c0a433c2518', + "latin-1-path-encoding", + {:reverse => true}) do |rev| + revs1 << rev + end + assert_equal 7, revs1.length + assert_equal '899a15dba03a3b350b89c3f537e4bbe02a03cdc9', revs1[ 0].identifier + assert_equal '1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127', revs1[-1].identifier + + revs2 = [] + @adapter.revisions('', + '57ca437c0acbbcb749821fdf3726a1367056d364', + "latin-1-path-encoding", + {:reverse => true}) do |rev| + revs2 << rev + end + assert_equal 3, revs2.length + assert_equal '4fc55c43bf3d3dc2efb66145365ddc17639ce81e', revs2[ 0].identifier + assert_equal '1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127', revs2[-1].identifier + end - def test_revisions_includes_master_two_revs_from_origin + def test_revisions_invalid_rev + assert_equal [], @adapter.revisions('', '1234abcd', "master") + assert_raise Redmine::Scm::Adapters::CommandFailed do revs1 = [] - @adapter.revisions('', nil, nil, - {:reverse => true, - :includes => ['899a15dba03a3b350b89c3f537e4bbe02a03cdc9'], - :excludes => []}) do |rev| + @adapter.revisions('', + '1234abcd', + "master", + {:reverse => true}) do |rev| revs1 << rev end - assert_equal 2, revs1.length - assert_equal '7234cb2750b63f47bff735edc50a1c0a433c2518', revs1[ 0].identifier - assert_equal '899a15dba03a3b350b89c3f537e4bbe02a03cdc9', revs1[ 1].identifier end + end - def test_revisions_includes_merged_revs - revs1 = [] - @adapter.revisions('', nil, nil, - {:reverse => true, - :includes => ['83ca5fd546063a3c7dc2e568ba3355661a9e2b2c'], - :excludes => ['fba357b886984ee71185ad2065e65fc0417d9b92']}) do |rev| - revs1 << rev - end - assert_equal 7, revs1.length - assert_equal '7e61ac704deecde634b51e59daa8110435dcb3da', revs1[ 0].identifier - assert_equal '4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8', revs1[ 1].identifier - assert_equal '32ae898b720c2f7eec2723d5bdd558b4cb2d3ddf', revs1[ 2].identifier - assert_equal '83ca5fd546063a3c7dc2e568ba3355661a9e2b2c', revs1[-1].identifier - end + def test_revisions_includes_master_two_revs + revs1 = [] + @adapter.revisions('', nil, nil, + {:reverse => true, + :includes => ['83ca5fd546063a3c7dc2e568ba3355661a9e2b2c'], + :excludes => ['4f26664364207fa8b1af9f8722647ab2d4ac5d43']}) do |rev| + revs1 << rev + end + assert_equal 2, revs1.length + assert_equal 'ed5bb786bbda2dee66a2d50faf51429dbc043a7b', revs1[ 0].identifier + assert_equal '83ca5fd546063a3c7dc2e568ba3355661a9e2b2c', revs1[-1].identifier + end - def test_revisions_includes_two_heads - revs1 = [] - @adapter.revisions('', nil, nil, - {:reverse => true, - :includes => ['83ca5fd546063a3c7dc2e568ba3355661a9e2b2c', - '1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127'], - :excludes => ['4f26664364207fa8b1af9f8722647ab2d4ac5d43', - '4fc55c43bf3d3dc2efb66145365ddc17639ce81e']}) do |rev| - revs1 << rev - end - assert_equal 4, revs1.length - assert_equal 'ed5bb786bbda2dee66a2d50faf51429dbc043a7b', revs1[ 0].identifier - assert_equal '83ca5fd546063a3c7dc2e568ba3355661a9e2b2c', revs1[ 1].identifier - assert_equal '64f1f3e89ad1cb57976ff0ad99a107012ba3481d', revs1[-2].identifier - assert_equal '1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127', revs1[-1].identifier - end + def test_revisions_includes_master_two_revs_from_origin + revs1 = [] + @adapter.revisions('', nil, nil, + {:reverse => true, + :includes => ['899a15dba03a3b350b89c3f537e4bbe02a03cdc9'], + :excludes => []}) do |rev| + revs1 << rev + end + assert_equal 2, revs1.length + assert_equal '7234cb2750b63f47bff735edc50a1c0a433c2518', revs1[ 0].identifier + assert_equal '899a15dba03a3b350b89c3f537e4bbe02a03cdc9', revs1[ 1].identifier + end - def test_revisions_disjointed_histories_revisions + def test_revisions_includes_merged_revs + revs1 = [] + @adapter.revisions('', nil, nil, + {:reverse => true, + :includes => ['83ca5fd546063a3c7dc2e568ba3355661a9e2b2c'], + :excludes => ['fba357b886984ee71185ad2065e65fc0417d9b92']}) do |rev| + revs1 << rev + end + assert_equal 7, revs1.length + assert_equal '7e61ac704deecde634b51e59daa8110435dcb3da', revs1[ 0].identifier + assert_equal '4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8', revs1[ 1].identifier + assert_equal '32ae898b720c2f7eec2723d5bdd558b4cb2d3ddf', revs1[ 2].identifier + assert_equal '83ca5fd546063a3c7dc2e568ba3355661a9e2b2c', revs1[-1].identifier + end + + def test_revisions_includes_two_heads + revs1 = [] + @adapter.revisions('', nil, nil, + {:reverse => true, + :includes => ['83ca5fd546063a3c7dc2e568ba3355661a9e2b2c', + '1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127'], + :excludes => ['4f26664364207fa8b1af9f8722647ab2d4ac5d43', + '4fc55c43bf3d3dc2efb66145365ddc17639ce81e']}) do |rev| + revs1 << rev + end + assert_equal 4, revs1.length + assert_equal 'ed5bb786bbda2dee66a2d50faf51429dbc043a7b', revs1[ 0].identifier + assert_equal '83ca5fd546063a3c7dc2e568ba3355661a9e2b2c', revs1[ 1].identifier + assert_equal '64f1f3e89ad1cb57976ff0ad99a107012ba3481d', revs1[-2].identifier + assert_equal '1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127', revs1[-1].identifier + end + + def test_revisions_disjointed_histories_revisions + revs1 = [] + @adapter.revisions('', nil, nil, + {:reverse => true, + :includes => ['83ca5fd546063a3c7dc2e568ba3355661a9e2b2c', + '92397af84d22f27389c822848ecd5b463c181583'], + :excludes => ['95488a44bc25f7d1f97d775a31359539ff333a63', + '4f26664364207fa8b1af9f8722647ab2d4ac5d43'] }) do |rev| + revs1 << rev + end + assert_equal 4, revs1.length + assert_equal 'ed5bb786bbda2dee66a2d50faf51429dbc043a7b', revs1[ 0].identifier + assert_equal '83ca5fd546063a3c7dc2e568ba3355661a9e2b2c', revs1[ 1].identifier + assert_equal 'bc201c95999c4f10d018b0aa03b541cd6a2ff0ee', revs1[-2].identifier + assert_equal '92397af84d22f27389c822848ecd5b463c181583', revs1[-1].identifier + end + + def test_revisions_invalid_rev_excludes + assert_equal [], + @adapter.revisions('', nil, nil, + {:reverse => true, + :includes => ['83ca5fd546063a3c7dc2e568ba3355661a9e2b2c'], + :excludes => ['0123abcd4567']}) + assert_raise Redmine::Scm::Adapters::CommandFailed do revs1 = [] @adapter.revisions('', nil, nil, {:reverse => true, - :includes => ['83ca5fd546063a3c7dc2e568ba3355661a9e2b2c', - '92397af84d22f27389c822848ecd5b463c181583'], - :excludes => ['95488a44bc25f7d1f97d775a31359539ff333a63', - '4f26664364207fa8b1af9f8722647ab2d4ac5d43'] }) do |rev| + :includes => ['83ca5fd546063a3c7dc2e568ba3355661a9e2b2c'], + :excludes => ['0123abcd4567']}) do |rev| revs1 << rev end - assert_equal 4, revs1.length - assert_equal 'ed5bb786bbda2dee66a2d50faf51429dbc043a7b', revs1[ 0].identifier - assert_equal '83ca5fd546063a3c7dc2e568ba3355661a9e2b2c', revs1[ 1].identifier - assert_equal 'bc201c95999c4f10d018b0aa03b541cd6a2ff0ee', revs1[-2].identifier - assert_equal '92397af84d22f27389c822848ecd5b463c181583', revs1[-1].identifier - end - - def test_revisions_invalid_rev_excludes - assert_equal [], - @adapter.revisions('', nil, nil, - {:reverse => true, - :includes => ['83ca5fd546063a3c7dc2e568ba3355661a9e2b2c'], - :excludes => ['0123abcd4567']}) - assert_raise Redmine::Scm::Adapters::CommandFailed do - revs1 = [] - @adapter.revisions('', nil, nil, - {:reverse => true, - :includes => ['83ca5fd546063a3c7dc2e568ba3355661a9e2b2c'], - :excludes => ['0123abcd4567']}) do |rev| - revs1 << rev - end - end end + end - def test_getting_revisions_with_spaces_in_filename - assert_equal 1, @adapter.revisions("filemane with spaces.txt", - nil, "master").length - end + def test_getting_revisions_with_spaces_in_filename + assert_equal 1, @adapter.revisions("filemane with spaces.txt", + nil, "master").length + end - def test_parents - revs1 = [] - @adapter.revisions('', - nil, - "master", - {:reverse => true}) do |rev| - revs1 << rev - end - assert_equal 15, revs1.length - assert_equal "7234cb2750b63f47bff735edc50a1c0a433c2518", - revs1[0].identifier - assert_equal nil, revs1[0].parents - assert_equal "899a15dba03a3b350b89c3f537e4bbe02a03cdc9", - revs1[1].identifier - assert_equal 1, revs1[1].parents.length - assert_equal "7234cb2750b63f47bff735edc50a1c0a433c2518", - revs1[1].parents[0] - assert_equal "32ae898b720c2f7eec2723d5bdd558b4cb2d3ddf", - revs1[10].identifier - assert_equal 2, revs1[10].parents.length - assert_equal "4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8", - revs1[10].parents[0] - assert_equal "7e61ac704deecde634b51e59daa8110435dcb3da", - revs1[10].parents[1] - end + def test_parents + revs1 = [] + @adapter.revisions('', + nil, + "master", + {:reverse => true}) do |rev| + revs1 << rev + end + assert_equal 15, revs1.length + assert_equal "7234cb2750b63f47bff735edc50a1c0a433c2518", + revs1[0].identifier + assert_equal nil, revs1[0].parents + assert_equal "899a15dba03a3b350b89c3f537e4bbe02a03cdc9", + revs1[1].identifier + assert_equal 1, revs1[1].parents.length + assert_equal "7234cb2750b63f47bff735edc50a1c0a433c2518", + revs1[1].parents[0] + assert_equal "32ae898b720c2f7eec2723d5bdd558b4cb2d3ddf", + revs1[10].identifier + assert_equal 2, revs1[10].parents.length + assert_equal "4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8", + revs1[10].parents[0] + assert_equal "7e61ac704deecde634b51e59daa8110435dcb3da", + revs1[10].parents[1] + end - def test_getting_revisions_with_leading_and_trailing_spaces_in_filename - assert_equal " filename with a leading space.txt ", - @adapter.revisions(" filename with a leading space.txt ", - nil, "master")[0].paths[0][:path] - end + def test_getting_revisions_with_leading_and_trailing_spaces_in_filename + assert_equal " filename with a leading space.txt ", + @adapter.revisions(" filename with a leading space.txt ", + nil, "master")[0].paths[0][:path] + end - def test_getting_entries_with_leading_and_trailing_spaces_in_filename - assert_equal " filename with a leading space.txt ", - @adapter.entries('', - '83ca5fd546063a3c7dc2e568ba3355661a9e2b2c')[3].name - end + def test_getting_entries_with_leading_and_trailing_spaces_in_filename + assert_equal " filename with a leading space.txt ", + @adapter.entries('', + '83ca5fd546063a3c7dc2e568ba3355661a9e2b2c')[3].name + end - def test_annotate - annotate = @adapter.annotate('sources/watchers_controller.rb') - assert_kind_of Redmine::Scm::Adapters::Annotate, annotate - assert_equal 41, annotate.lines.size - assert_equal "# This program is free software; you can redistribute it and/or", - annotate.lines[4].strip - assert_equal "7234cb2750b63f47bff735edc50a1c0a433c2518", - annotate.revisions[4].identifier - assert_equal "jsmith", annotate.revisions[4].author - end + def test_annotate + annotate = @adapter.annotate('sources/watchers_controller.rb') + assert_kind_of Redmine::Scm::Adapters::Annotate, annotate + assert_equal 41, annotate.lines.size + assert_equal "# This program is free software; you can redistribute it and/or", + annotate.lines[4].strip + assert_equal "7234cb2750b63f47bff735edc50a1c0a433c2518", + annotate.revisions[4].identifier + assert_equal "jsmith", annotate.revisions[4].author + end - def test_annotate_moved_file - annotate = @adapter.annotate('renamed_test.txt') - assert_kind_of Redmine::Scm::Adapters::Annotate, annotate - assert_equal 2, annotate.lines.size - end + def test_annotate_moved_file + annotate = @adapter.annotate('renamed_test.txt') + assert_kind_of Redmine::Scm::Adapters::Annotate, annotate + assert_equal 2, annotate.lines.size + end - def test_last_rev - last_rev = @adapter.lastrev("README", - "4f26664364207fa8b1af9f8722647ab2d4ac5d43") - assert_equal "4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8", last_rev.scmid - assert_equal "4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8", last_rev.identifier - assert_equal "Adam Soltys <asoltys@gmail.com>", last_rev.author - assert_equal Time.gm(2009, 6, 24, 5, 27, 38), last_rev.time - end + def test_last_rev + last_rev = @adapter.lastrev("README", + "4f26664364207fa8b1af9f8722647ab2d4ac5d43") + assert_equal "4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8", last_rev.scmid + assert_equal "4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8", last_rev.identifier + assert_equal "Adam Soltys <asoltys@gmail.com>", last_rev.author + assert_equal Time.gm(2009, 6, 24, 5, 27, 38), last_rev.time + end - def test_last_rev_with_spaces_in_filename - last_rev = @adapter.lastrev("filemane with spaces.txt", - "ed5bb786bbda2dee66a2d50faf51429dbc043a7b") - last_rev_author = last_rev.author - assert_equal "ed5bb786bbda2dee66a2d50faf51429dbc043a7b", last_rev.scmid - assert_equal "ed5bb786bbda2dee66a2d50faf51429dbc043a7b", last_rev.identifier - assert_equal "#{@str_felix_hex} <felix@fachschaften.org>", - last_rev.author - assert_equal Time.gm(2010, 9, 18, 19, 59, 46), last_rev.time - end + def test_last_rev_with_spaces_in_filename + last_rev = @adapter.lastrev("filemane with spaces.txt", + "ed5bb786bbda2dee66a2d50faf51429dbc043a7b") + last_rev_author = last_rev.author + assert_equal "ed5bb786bbda2dee66a2d50faf51429dbc043a7b", last_rev.scmid + assert_equal "ed5bb786bbda2dee66a2d50faf51429dbc043a7b", last_rev.identifier + assert_equal "#{@str_felix_hex} <felix@fachschaften.org>", + last_rev.author + assert_equal Time.gm(2010, 9, 18, 19, 59, 46), last_rev.time + end - def test_latin_1_path - if WINDOWS_PASS - puts WINDOWS_SKIP_STR - elsif JRUBY_SKIP - puts JRUBY_SKIP_STR - else - p2 = "latin-1-dir/test-#{@char_1}-2.txt" - ['4fc55c43bf3d3dc2efb66145365ddc17639ce81e', '4fc55c43bf3'].each do |r1| - assert @adapter.diff(p2, r1) - assert @adapter.cat(p2, r1) - assert_equal 1, @adapter.annotate(p2, r1).lines.length - ['64f1f3e89ad1cb57976ff0ad99a107012ba3481d', '64f1f3e89ad1cb5797'].each do |r2| - assert @adapter.diff(p2, r1, r2) - end + def test_latin_1_path + if WINDOWS_PASS + puts WINDOWS_SKIP_STR + elsif JRUBY_SKIP + puts JRUBY_SKIP_STR + else + p2 = "latin-1-dir/test-#{@char_1}-2.txt" + ['4fc55c43bf3d3dc2efb66145365ddc17639ce81e', '4fc55c43bf3'].each do |r1| + assert @adapter.diff(p2, r1) + assert @adapter.cat(p2, r1) + assert_equal 1, @adapter.annotate(p2, r1).lines.length + ['64f1f3e89ad1cb57976ff0ad99a107012ba3481d', '64f1f3e89ad1cb5797'].each do |r2| + assert @adapter.diff(p2, r1, r2) end end end + end - def test_latin_1_user_annotate - ['83ca5fd546063a3c7dc2e568ba3355661a9e2b2c', '83ca5fd546063a'].each do |r1| - annotate = @adapter.annotate(" filename with a leading space.txt ", r1) - assert_kind_of Redmine::Scm::Adapters::Annotate, annotate - assert_equal 1, annotate.lines.size - assert_equal "And this is a file with a leading and trailing space...", - annotate.lines[0].strip - assert_equal "83ca5fd546063a3c7dc2e568ba3355661a9e2b2c", - annotate.revisions[0].identifier - assert_equal @str_felix_hex, annotate.revisions[0].author - end + def test_latin_1_user_annotate + ['83ca5fd546063a3c7dc2e568ba3355661a9e2b2c', '83ca5fd546063a'].each do |r1| + annotate = @adapter.annotate(" filename with a leading space.txt ", r1) + assert_kind_of Redmine::Scm::Adapters::Annotate, annotate + assert_equal 1, annotate.lines.size + assert_equal "And this is a file with a leading and trailing space...", + annotate.lines[0].strip + assert_equal "83ca5fd546063a3c7dc2e568ba3355661a9e2b2c", + annotate.revisions[0].identifier + assert_equal @str_felix_hex, annotate.revisions[0].author end + end - def test_entries_tag - entries1 = @adapter.entries(nil, 'tag01.annotated', - options = {:report_last_commit => true}) - assert entries1 - assert_equal 3, entries1.size - assert_equal 'sources', entries1[1].name - assert_equal 'sources', entries1[1].path - assert_equal 'dir', entries1[1].kind - readme = entries1[2] - assert_equal 'README', readme.name - assert_equal 'README', readme.path - assert_equal 'file', readme.kind - assert_equal 27, readme.size - assert_equal '899a15dba03a3b350b89c3f537e4bbe02a03cdc9', readme.lastrev.identifier - assert_equal Time.gm(2007, 12, 14, 9, 24, 1), readme.lastrev.time - end + def test_entries_tag + entries1 = @adapter.entries(nil, 'tag01.annotated', + options = {:report_last_commit => true}) + assert entries1 + assert_equal 3, entries1.size + assert_equal 'sources', entries1[1].name + assert_equal 'sources', entries1[1].path + assert_equal 'dir', entries1[1].kind + readme = entries1[2] + assert_equal 'README', readme.name + assert_equal 'README', readme.path + assert_equal 'file', readme.kind + assert_equal 27, readme.size + assert_equal '899a15dba03a3b350b89c3f537e4bbe02a03cdc9', readme.lastrev.identifier + assert_equal Time.gm(2007, 12, 14, 9, 24, 1), readme.lastrev.time + end - def test_entries_branch - entries1 = @adapter.entries(nil, 'test_branch', - options = {:report_last_commit => true}) - assert entries1 - assert_equal 4, entries1.size - assert_equal 'sources', entries1[1].name - assert_equal 'sources', entries1[1].path - assert_equal 'dir', entries1[1].kind - readme = entries1[2] - assert_equal 'README', readme.name - assert_equal 'README', readme.path - assert_equal 'file', readme.kind - assert_equal 159, readme.size - assert_equal '713f4944648826f558cf548222f813dabe7cbb04', readme.lastrev.identifier - assert_equal Time.gm(2009, 6, 19, 4, 37, 23), readme.lastrev.time - end + def test_entries_branch + entries1 = @adapter.entries(nil, 'test_branch', + options = {:report_last_commit => true}) + assert entries1 + assert_equal 4, entries1.size + assert_equal 'sources', entries1[1].name + assert_equal 'sources', entries1[1].path + assert_equal 'dir', entries1[1].kind + readme = entries1[2] + assert_equal 'README', readme.name + assert_equal 'README', readme.path + assert_equal 'file', readme.kind + assert_equal 159, readme.size + assert_equal '713f4944648826f558cf548222f813dabe7cbb04', readme.lastrev.identifier + assert_equal Time.gm(2009, 6, 19, 4, 37, 23), readme.lastrev.time + end - def test_entries_wrong_path_encoding - adpt = Redmine::Scm::Adapters::GitAdapter.new( - REPOSITORY_PATH, - nil, - nil, - nil, - 'EUC-JP' - ) - entries1 = adpt.entries('latin-1-dir', '64f1f3e8') - assert entries1 - assert_equal 3, entries1.size - f1 = entries1[1] - assert_equal nil, f1.name - assert_equal nil, f1.path - assert_equal 'file', f1.kind - end + def test_entries_wrong_path_encoding + adpt = Redmine::Scm::Adapters::GitAdapter.new( + REPOSITORY_PATH, + nil, + nil, + nil, + 'EUC-JP' + ) + entries1 = adpt.entries('latin-1-dir', '64f1f3e8') + assert entries1 + assert_equal 3, entries1.size + f1 = entries1[1] + assert_equal nil, f1.name + assert_equal nil, f1.path + assert_equal 'file', f1.kind + end + + def test_entries_latin_1_files + entries1 = @adapter.entries('latin-1-dir', '64f1f3e8') + assert entries1 + assert_equal 3, entries1.size + f1 = entries1[1] + assert_equal "test-#{@char_1}-2.txt", f1.name + assert_equal "latin-1-dir/test-#{@char_1}-2.txt", f1.path + assert_equal 'file', f1.kind + end - def test_entries_latin_1_files - entries1 = @adapter.entries('latin-1-dir', '64f1f3e8') + def test_entries_latin_1_dir + if WINDOWS_PASS + puts WINDOWS_SKIP_STR + elsif JRUBY_SKIP + puts JRUBY_SKIP_STR + else + entries1 = @adapter.entries("latin-1-dir/test-#{@char_1}-subdir", + '1ca7f5ed') assert entries1 assert_equal 3, entries1.size f1 = entries1[1] assert_equal "test-#{@char_1}-2.txt", f1.name - assert_equal "latin-1-dir/test-#{@char_1}-2.txt", f1.path + assert_equal "latin-1-dir/test-#{@char_1}-subdir/test-#{@char_1}-2.txt", f1.path assert_equal 'file', f1.kind end + end - def test_entries_latin_1_dir - if WINDOWS_PASS - puts WINDOWS_SKIP_STR - elsif JRUBY_SKIP - puts JRUBY_SKIP_STR - else - entries1 = @adapter.entries("latin-1-dir/test-#{@char_1}-subdir", - '1ca7f5ed') - assert entries1 - assert_equal 3, entries1.size - f1 = entries1[1] - assert_equal "test-#{@char_1}-2.txt", f1.name - assert_equal "latin-1-dir/test-#{@char_1}-subdir/test-#{@char_1}-2.txt", f1.path - assert_equal 'file', f1.kind - end - end - - def test_entry - entry = @adapter.entry() - assert_equal "", entry.path + def test_entry + entry = @adapter.entry() + assert_equal "", entry.path + assert_equal "dir", entry.kind + entry = @adapter.entry('') + assert_equal "", entry.path + assert_equal "dir", entry.kind + assert_nil @adapter.entry('invalid') + assert_nil @adapter.entry('/invalid') + assert_nil @adapter.entry('/invalid/') + assert_nil @adapter.entry('invalid/invalid') + assert_nil @adapter.entry('invalid/invalid/') + assert_nil @adapter.entry('/invalid/invalid') + assert_nil @adapter.entry('/invalid/invalid/') + ["README", "/README"].each do |path| + entry = @adapter.entry(path, '7234cb2750b63f') + assert_equal "README", entry.path + assert_equal "file", entry.kind + end + ["sources", "/sources", "/sources/"].each do |path| + entry = @adapter.entry(path, '7234cb2750b63f') + assert_equal "sources", entry.path assert_equal "dir", entry.kind - entry = @adapter.entry('') - assert_equal "", entry.path - assert_equal "dir", entry.kind - assert_nil @adapter.entry('invalid') - assert_nil @adapter.entry('/invalid') - assert_nil @adapter.entry('/invalid/') - assert_nil @adapter.entry('invalid/invalid') - assert_nil @adapter.entry('invalid/invalid/') - assert_nil @adapter.entry('/invalid/invalid') - assert_nil @adapter.entry('/invalid/invalid/') - ["README", "/README"].each do |path| - entry = @adapter.entry(path, '7234cb2750b63f') - assert_equal "README", entry.path - assert_equal "file", entry.kind - end - ["sources", "/sources", "/sources/"].each do |path| - entry = @adapter.entry(path, '7234cb2750b63f') - assert_equal "sources", entry.path - assert_equal "dir", entry.kind - end - ["sources/watchers_controller.rb", "/sources/watchers_controller.rb"].each do |path| - entry = @adapter.entry(path, '7234cb2750b63f') - assert_equal "sources/watchers_controller.rb", entry.path - assert_equal "file", entry.kind - end end - - def test_path_encoding_default_utf8 - adpt1 = Redmine::Scm::Adapters::GitAdapter.new( - REPOSITORY_PATH - ) - assert_equal "UTF-8", adpt1.path_encoding - adpt2 = Redmine::Scm::Adapters::GitAdapter.new( - REPOSITORY_PATH, - nil, - nil, - nil, - "" - ) - assert_equal "UTF-8", adpt2.path_encoding + ["sources/watchers_controller.rb", "/sources/watchers_controller.rb"].each do |path| + entry = @adapter.entry(path, '7234cb2750b63f') + assert_equal "sources/watchers_controller.rb", entry.path + assert_equal "file", entry.kind end + end - def test_cat_path_invalid - assert_nil @adapter.cat('invalid') - end + def test_path_encoding_default_utf8 + adpt1 = Redmine::Scm::Adapters::GitAdapter.new( + REPOSITORY_PATH + ) + assert_equal "UTF-8", adpt1.path_encoding + adpt2 = Redmine::Scm::Adapters::GitAdapter.new( + REPOSITORY_PATH, + nil, + nil, + nil, + "" + ) + assert_equal "UTF-8", adpt2.path_encoding + end - def test_cat_revision_invalid - assert @adapter.cat('README') - assert_nil @adapter.cat('README', '1234abcd5678') - end + def test_cat_path_invalid + assert_nil @adapter.cat('invalid') + end - def test_diff_path_invalid - assert_equal [], @adapter.diff('invalid', '713f4944648826f5') - end + def test_cat_revision_invalid + assert @adapter.cat('README') + assert_nil @adapter.cat('README', '1234abcd5678') + end - def test_diff_revision_invalid - assert_nil @adapter.diff(nil, '1234abcd5678') - assert_nil @adapter.diff(nil, '713f4944648826f5', '1234abcd5678') - assert_nil @adapter.diff(nil, '1234abcd5678', '713f4944648826f5') - end + def test_diff_path_invalid + assert_equal [], @adapter.diff('invalid', '713f4944648826f5') + end - def test_annotate_path_invalid - assert_nil @adapter.annotate('invalid') - end + def test_diff_revision_invalid + assert_nil @adapter.diff(nil, '1234abcd5678') + assert_nil @adapter.diff(nil, '713f4944648826f5', '1234abcd5678') + assert_nil @adapter.diff(nil, '1234abcd5678', '713f4944648826f5') + end - def test_annotate_revision_invalid - assert @adapter.annotate('README') - assert_nil @adapter.annotate('README', '1234abcd5678') - end + def test_annotate_path_invalid + assert_nil @adapter.annotate('invalid') + end - private + def test_annotate_revision_invalid + assert @adapter.annotate('README') + assert_nil @adapter.annotate('README', '1234abcd5678') + end - def test_scm_version_for(scm_command_version, version) - @adapter.class.expects(:scm_version_from_command_line).returns(scm_command_version) - assert_equal version, @adapter.class.scm_command_version - end + private - else - puts "Git test repository NOT FOUND. Skipping unit tests !!!" - def test_fake; assert true end + def test_scm_version_for(scm_command_version, version) + @adapter.class.expects(:scm_version_from_command_line).returns(scm_command_version) + assert_equal version, @adapter.class.scm_command_version end - end -rescue LoadError - class GitMochaFake < ActiveSupport::TestCase - def test_fake; assert(false, "Requires mocha to run those tests") end + else + puts "Git test repository NOT FOUND. Skipping unit tests !!!" + def test_fake; assert true end end end diff --git a/test/unit/lib/redmine/scm/adapters/mercurial_adapter_test.rb b/test/unit/lib/redmine/scm/adapters/mercurial_adapter_test.rb index 7f062d1f1..ebbb75008 100644 --- a/test/unit/lib/redmine/scm/adapters/mercurial_adapter_test.rb +++ b/test/unit/lib/redmine/scm/adapters/mercurial_adapter_test.rb @@ -16,221 +16,184 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. require File.expand_path('../../../../../../test_helper', __FILE__) -begin - require 'mocha/setup' - - class MercurialAdapterTest < ActiveSupport::TestCase - HELPERS_DIR = Redmine::Scm::Adapters::MercurialAdapter::HELPERS_DIR - TEMPLATE_NAME = Redmine::Scm::Adapters::MercurialAdapter::TEMPLATE_NAME - TEMPLATE_EXTENSION = Redmine::Scm::Adapters::MercurialAdapter::TEMPLATE_EXTENSION - - REPOSITORY_PATH = Rails.root.join('tmp/test/mercurial_repository').to_s - CHAR_1_HEX = "\xc3\x9c" - - if File.directory?(REPOSITORY_PATH) - def setup - adapter_class = Redmine::Scm::Adapters::MercurialAdapter - assert adapter_class - assert adapter_class.client_command - assert_equal true, adapter_class.client_available - assert_equal true, adapter_class.client_version_above?([0, 9, 5]) - - @adapter = Redmine::Scm::Adapters::MercurialAdapter.new( - REPOSITORY_PATH, - nil, - nil, - nil, - 'ISO-8859-1') - @diff_c_support = true - @char_1 = CHAR_1_HEX.dup - @tag_char_1 = "tag-#{CHAR_1_HEX}-00" - @branch_char_0 = "branch-#{CHAR_1_HEX}-00" - @branch_char_1 = "branch-#{CHAR_1_HEX}-01" - if @tag_char_1.respond_to?(:force_encoding) - @char_1.force_encoding('UTF-8') - @tag_char_1.force_encoding('UTF-8') - @branch_char_0.force_encoding('UTF-8') - @branch_char_1.force_encoding('UTF-8') - end - end - def test_hgversion - to_test = { "Mercurial Distributed SCM (version 0.9.5)\n" => [0,9,5], - "Mercurial Distributed SCM (1.0)\n" => [1,0], - "Mercurial Distributed SCM (1e4ddc9ac9f7+20080325)\n" => nil, - "Mercurial Distributed SCM (1.0.1+20080525)\n" => [1,0,1], - "Mercurial Distributed SCM (1916e629a29d)\n" => nil, - "Mercurial SCM Distribuito (versione 0.9.5)\n" => [0,9,5], - "(1.6)\n(1.7)\n(1.8)" => [1,6], - "(1.7.1)\r\n(1.8.1)\r\n(1.9.1)" => [1,7,1]} - - to_test.each do |s, v| - test_hgversion_for(s, v) - end - end +class MercurialAdapterTest < ActiveSupport::TestCase + HELPERS_DIR = Redmine::Scm::Adapters::MercurialAdapter::HELPERS_DIR + TEMPLATE_NAME = Redmine::Scm::Adapters::MercurialAdapter::TEMPLATE_NAME + TEMPLATE_EXTENSION = Redmine::Scm::Adapters::MercurialAdapter::TEMPLATE_EXTENSION + + REPOSITORY_PATH = repository_path('mercurial') + CHAR_1_HEX = "\xc3\x9c" + + if File.directory?(REPOSITORY_PATH) + def setup + adapter_class = Redmine::Scm::Adapters::MercurialAdapter + assert adapter_class + assert adapter_class.client_command + assert_equal true, adapter_class.client_available + assert_equal true, adapter_class.client_version_above?([0, 9, 5]) + + @adapter = Redmine::Scm::Adapters::MercurialAdapter.new( + REPOSITORY_PATH, + nil, + nil, + nil, + 'ISO-8859-1') + @diff_c_support = true + @char_1 = CHAR_1_HEX.dup.force_encoding('UTF-8') + @tag_char_1 = "tag-#{CHAR_1_HEX}-00".force_encoding('UTF-8') + @branch_char_0 = "branch-#{CHAR_1_HEX}-00".force_encoding('UTF-8') + @branch_char_1 = "branch-#{CHAR_1_HEX}-01".force_encoding('UTF-8') + end - def test_template_path - to_test = { - [1,2] => "1.0", - [] => "1.0", - [1,2,1] => "1.0", - [1,7] => "1.0", - [1,7,1] => "1.0", - [2,0] => "1.0", - } - to_test.each do |v, template| - test_template_path_for(v, template) - end + def test_hgversion + to_test = { "Mercurial Distributed SCM (version 0.9.5)\n" => [0,9,5], + "Mercurial Distributed SCM (1.0)\n" => [1,0], + "Mercurial Distributed SCM (1e4ddc9ac9f7+20080325)\n" => nil, + "Mercurial Distributed SCM (1.0.1+20080525)\n" => [1,0,1], + "Mercurial Distributed SCM (1916e629a29d)\n" => nil, + "Mercurial SCM Distribuito (versione 0.9.5)\n" => [0,9,5], + "(1.6)\n(1.7)\n(1.8)" => [1,6], + "(1.7.1)\r\n(1.8.1)\r\n(1.9.1)" => [1,7,1]} + + to_test.each do |s, v| + test_hgversion_for(s, v) end + end - def test_info - [REPOSITORY_PATH, REPOSITORY_PATH + "/", - REPOSITORY_PATH + "//"].each do |repo| - adp = Redmine::Scm::Adapters::MercurialAdapter.new(repo) - repo_path = adp.info.root_url.gsub(/\\/, "/") - assert_equal REPOSITORY_PATH, repo_path - assert_equal '33', adp.info.lastrev.revision - assert_equal '2e6d546429230f377d7d19c2078abd2dd909f235',adp.info.lastrev.scmid - end + def test_template_path + to_test = { + [1,2] => "1.0", + [] => "1.0", + [1,2,1] => "1.0", + [1,7] => "1.0", + [1,7,1] => "1.0", + [2,0] => "1.0", + } + to_test.each do |v, template| + test_template_path_for(v, template) end + end - def test_revisions - revisions = @adapter.revisions(nil, 2, 4) - assert_equal 3, revisions.size - assert_equal '2', revisions[0].revision - assert_equal '400bb86721098697c7d17b3724c794c57636de70', revisions[0].scmid - assert_equal '4', revisions[2].revision - assert_equal 'def6d2f1254a56fb8fbe9ec3b5c0451674dbd8b8', revisions[2].scmid - - revisions = @adapter.revisions(nil, 2, 4, {:limit => 2}) - assert_equal 2, revisions.size - assert_equal '2', revisions[0].revision - assert_equal '400bb86721098697c7d17b3724c794c57636de70', revisions[0].scmid + def test_info + [REPOSITORY_PATH, REPOSITORY_PATH + "/", + REPOSITORY_PATH + "//"].each do |repo| + adp = Redmine::Scm::Adapters::MercurialAdapter.new(repo) + repo_path = adp.info.root_url.gsub(/\\/, "/") + assert_equal REPOSITORY_PATH, repo_path + assert_equal '33', adp.info.lastrev.revision + assert_equal '2e6d546429230f377d7d19c2078abd2dd909f235',adp.info.lastrev.scmid end + end - def test_parents - revs1 = @adapter.revisions(nil, 0, 0) - assert_equal 1, revs1.size - assert_equal [], revs1[0].parents - revs2 = @adapter.revisions(nil, 1, 1) - assert_equal 1, revs2.size - assert_equal 1, revs2[0].parents.size - assert_equal "0885933ad4f68d77c2649cd11f8311276e7ef7ce", revs2[0].parents[0] - revs3 = @adapter.revisions(nil, 30, 30) - assert_equal 1, revs3.size - assert_equal 2, revs3[0].parents.size - assert_equal "a94b0528f24fe05ebaef496ae0500bb050772e36", revs3[0].parents[0] - assert_equal "3a330eb329586ea2adb3f83237c23310e744ebe9", revs3[0].parents[1] - end + def test_revisions + revisions = @adapter.revisions(nil, 2, 4) + assert_equal 3, revisions.size + assert_equal '2', revisions[0].revision + assert_equal '400bb86721098697c7d17b3724c794c57636de70', revisions[0].scmid + assert_equal '4', revisions[2].revision + assert_equal 'def6d2f1254a56fb8fbe9ec3b5c0451674dbd8b8', revisions[2].scmid + + revisions = @adapter.revisions(nil, 2, 4, {:limit => 2}) + assert_equal 2, revisions.size + assert_equal '2', revisions[0].revision + assert_equal '400bb86721098697c7d17b3724c794c57636de70', revisions[0].scmid + end - def test_diff - if @adapter.class.client_version_above?([1, 2]) - assert_nil @adapter.diff(nil, '100000') - end - assert_nil @adapter.diff(nil, '100000', '200000') - [2, '400bb8672109', '400', 400].each do |r1| - diff1 = @adapter.diff(nil, r1) - if @diff_c_support - assert_equal 28, diff1.size - buf = diff1[24].gsub(/\r\n|\r|\n/, "") - assert_equal "+ return true unless klass.respond_to?('watched_by')", buf - else - assert_equal 0, diff1.size - end - [4, 'def6d2f1254a'].each do |r2| - diff2 = @adapter.diff(nil, r1, r2) - assert_equal 49, diff2.size - buf = diff2[41].gsub(/\r\n|\r|\n/, "") - assert_equal "+class WelcomeController < ApplicationController", buf - diff3 = @adapter.diff('sources/watchers_controller.rb', r1, r2) - assert_equal 20, diff3.size - buf = diff3[12].gsub(/\r\n|\r|\n/, "") - assert_equal "+ @watched.remove_watcher(user)", buf - - diff4 = @adapter.diff(nil, r2, r1) - assert_equal 49, diff4.size - buf = diff4[41].gsub(/\r\n|\r|\n/, "") - assert_equal "-class WelcomeController < ApplicationController", buf - diff5 = @adapter.diff('sources/watchers_controller.rb', r2, r1) - assert_equal 20, diff5.size - buf = diff5[9].gsub(/\r\n|\r|\n/, "") - assert_equal "- @watched.remove_watcher(user)", buf - end - end - end + def test_parents + revs1 = @adapter.revisions(nil, 0, 0) + assert_equal 1, revs1.size + assert_equal [], revs1[0].parents + revs2 = @adapter.revisions(nil, 1, 1) + assert_equal 1, revs2.size + assert_equal 1, revs2[0].parents.size + assert_equal "0885933ad4f68d77c2649cd11f8311276e7ef7ce", revs2[0].parents[0] + revs3 = @adapter.revisions(nil, 30, 30) + assert_equal 1, revs3.size + assert_equal 2, revs3[0].parents.size + assert_equal "a94b0528f24fe05ebaef496ae0500bb050772e36", revs3[0].parents[0] + assert_equal "3a330eb329586ea2adb3f83237c23310e744ebe9", revs3[0].parents[1] + end - def test_diff_made_by_revision + def test_diff + if @adapter.class.client_version_above?([1, 2]) + assert_nil @adapter.diff(nil, '100000') + end + assert_nil @adapter.diff(nil, '100000', '200000') + [2, '400bb8672109', '400', 400].each do |r1| + diff1 = @adapter.diff(nil, r1) if @diff_c_support - [24, '24', '4cddb4e45f52'].each do |r1| - diff1 = @adapter.diff(nil, r1) - assert_equal 5, diff1.size - buf = diff1[4].gsub(/\r\n|\r|\n/, "") - assert_equal '+0885933ad4f68d77c2649cd11f8311276e7ef7ce tag-init-revision', buf - end + assert_equal 28, diff1.size + buf = diff1[24].gsub(/\r\n|\r|\n/, "") + assert_equal "+ return true unless klass.respond_to?('watched_by')", buf + else + assert_equal 0, diff1.size + end + [4, 'def6d2f1254a'].each do |r2| + diff2 = @adapter.diff(nil, r1, r2) + assert_equal 49, diff2.size + buf = diff2[41].gsub(/\r\n|\r|\n/, "") + assert_equal "+class WelcomeController < ApplicationController", buf + diff3 = @adapter.diff('sources/watchers_controller.rb', r1, r2) + assert_equal 20, diff3.size + buf = diff3[12].gsub(/\r\n|\r|\n/, "") + assert_equal "+ @watched.remove_watcher(user)", buf + + diff4 = @adapter.diff(nil, r2, r1) + assert_equal 49, diff4.size + buf = diff4[41].gsub(/\r\n|\r|\n/, "") + assert_equal "-class WelcomeController < ApplicationController", buf + diff5 = @adapter.diff('sources/watchers_controller.rb', r2, r1) + assert_equal 20, diff5.size + buf = diff5[9].gsub(/\r\n|\r|\n/, "") + assert_equal "- @watched.remove_watcher(user)", buf end end + end - def test_cat - [2, '400bb8672109', '400', 400].each do |r| - buf = @adapter.cat('sources/welcome_controller.rb', r) - assert buf - lines = buf.split("\r\n") - assert_equal 25, lines.length - assert_equal 'class WelcomeController < ApplicationController', lines[17] + def test_diff_made_by_revision + if @diff_c_support + [24, '24', '4cddb4e45f52'].each do |r1| + diff1 = @adapter.diff(nil, r1) + assert_equal 5, diff1.size + buf = diff1[4].gsub(/\r\n|\r|\n/, "") + assert_equal '+0885933ad4f68d77c2649cd11f8311276e7ef7ce tag-init-revision', buf end - assert_nil @adapter.cat('sources/welcome_controller.rb') end + end - def test_annotate - assert_equal [], @adapter.annotate("sources/welcome_controller.rb").lines - [2, '400bb8672109', '400', 400].each do |r| - ann = @adapter.annotate('sources/welcome_controller.rb', r) - assert ann - assert_equal '1', ann.revisions[17].revision - assert_equal '9d5b5b004199', ann.revisions[17].identifier - assert_equal 'jsmith', ann.revisions[0].author - assert_equal 25, ann.lines.length - assert_equal 'class WelcomeController < ApplicationController', ann.lines[17] - end + def test_cat + [2, '400bb8672109', '400', 400].each do |r| + buf = @adapter.cat('sources/welcome_controller.rb', r) + assert buf + lines = buf.split("\r\n") + assert_equal 25, lines.length + assert_equal 'class WelcomeController < ApplicationController', lines[17] end + assert_nil @adapter.cat('sources/welcome_controller.rb') + end - def test_entries - assert_nil @adapter.entries(nil, '100000') - - assert_equal 1, @adapter.entries("sources", 3).size - assert_equal 1, @adapter.entries("sources", 'b3a615152df8').size - - [2, '400bb8672109', '400', 400].each do |r| - entries1 = @adapter.entries(nil, r) - assert entries1 - assert_equal 3, entries1.size - assert_equal 'sources', entries1[1].name - assert_equal 'sources', entries1[1].path - assert_equal 'dir', entries1[1].kind - readme = entries1[2] - assert_equal 'README', readme.name - assert_equal 'README', readme.path - assert_equal 'file', readme.kind - assert_equal 27, readme.size - assert_equal '1', readme.lastrev.revision - assert_equal '9d5b5b00419901478496242e0768deba1ce8c51e', readme.lastrev.identifier - # 2007-12-14 10:24:01 +0100 - assert_equal Time.gm(2007, 12, 14, 9, 24, 1), readme.lastrev.time - - entries2 = @adapter.entries('sources', r) - assert entries2 - assert_equal 2, entries2.size - assert_equal 'watchers_controller.rb', entries2[0].name - assert_equal 'sources/watchers_controller.rb', entries2[0].path - assert_equal 'file', entries2[0].kind - assert_equal 'welcome_controller.rb', entries2[1].name - assert_equal 'sources/welcome_controller.rb', entries2[1].path - assert_equal 'file', entries2[1].kind - end + def test_annotate + assert_equal [], @adapter.annotate("sources/welcome_controller.rb").lines + [2, '400bb8672109', '400', 400].each do |r| + ann = @adapter.annotate('sources/welcome_controller.rb', r) + assert ann + assert_equal '1', ann.revisions[17].revision + assert_equal '9d5b5b004199', ann.revisions[17].identifier + assert_equal 'jsmith', ann.revisions[0].author + assert_equal 25, ann.lines.length + assert_equal 'class WelcomeController < ApplicationController', ann.lines[17] end + end + + def test_entries + assert_nil @adapter.entries(nil, '100000') - def test_entries_tag - entries1 = @adapter.entries(nil, 'tag_test.00') + assert_equal 1, @adapter.entries("sources", 3).size + assert_equal 1, @adapter.entries("sources", 'b3a615152df8').size + + [2, '400bb8672109', '400', 400].each do |r| + entries1 = @adapter.entries(nil, r) assert entries1 assert_equal 3, entries1.size assert_equal 'sources', entries1[1].name @@ -240,236 +203,260 @@ begin assert_equal 'README', readme.name assert_equal 'README', readme.path assert_equal 'file', readme.kind - assert_equal 21, readme.size - assert_equal '0', readme.lastrev.revision - assert_equal '0885933ad4f68d77c2649cd11f8311276e7ef7ce', readme.lastrev.identifier - # 2007-12-14 10:22:52 +0100 - assert_equal Time.gm(2007, 12, 14, 9, 22, 52), readme.lastrev.time + assert_equal 27, readme.size + assert_equal '1', readme.lastrev.revision + assert_equal '9d5b5b00419901478496242e0768deba1ce8c51e', readme.lastrev.identifier + # 2007-12-14 10:24:01 +0100 + assert_equal Time.gm(2007, 12, 14, 9, 24, 1), readme.lastrev.time + + entries2 = @adapter.entries('sources', r) + assert entries2 + assert_equal 2, entries2.size + assert_equal 'watchers_controller.rb', entries2[0].name + assert_equal 'sources/watchers_controller.rb', entries2[0].path + assert_equal 'file', entries2[0].kind + assert_equal 'welcome_controller.rb', entries2[1].name + assert_equal 'sources/welcome_controller.rb', entries2[1].path + assert_equal 'file', entries2[1].kind end + end - def test_entries_branch - entries1 = @adapter.entries(nil, 'test-branch-00') - assert entries1 - assert_equal 5, entries1.size - assert_equal 'sql_escape', entries1[2].name - assert_equal 'sql_escape', entries1[2].path - assert_equal 'dir', entries1[2].kind - readme = entries1[4] - assert_equal 'README', readme.name - assert_equal 'README', readme.path - assert_equal 'file', readme.kind - assert_equal 365, readme.size - assert_equal '8', readme.lastrev.revision - assert_equal 'c51f5bb613cd60793c2a9fe9df29332e74bb949f', readme.lastrev.identifier - # 2001-02-01 00:00:00 -0900 - assert_equal Time.gm(2001, 2, 1, 9, 0, 0), readme.lastrev.time - end + def test_entries_tag + entries1 = @adapter.entries(nil, 'tag_test.00') + assert entries1 + assert_equal 3, entries1.size + assert_equal 'sources', entries1[1].name + assert_equal 'sources', entries1[1].path + assert_equal 'dir', entries1[1].kind + readme = entries1[2] + assert_equal 'README', readme.name + assert_equal 'README', readme.path + assert_equal 'file', readme.kind + assert_equal 21, readme.size + assert_equal '0', readme.lastrev.revision + assert_equal '0885933ad4f68d77c2649cd11f8311276e7ef7ce', readme.lastrev.identifier + # 2007-12-14 10:22:52 +0100 + assert_equal Time.gm(2007, 12, 14, 9, 22, 52), readme.lastrev.time + end - def test_entry - entry = @adapter.entry() - assert_equal "", entry.path - assert_equal "dir", entry.kind - entry = @adapter.entry('') - assert_equal "", entry.path - assert_equal "dir", entry.kind - assert_nil @adapter.entry('invalid') - assert_nil @adapter.entry('/invalid') - assert_nil @adapter.entry('/invalid/') - assert_nil @adapter.entry('invalid/invalid') - assert_nil @adapter.entry('invalid/invalid/') - assert_nil @adapter.entry('/invalid/invalid') - assert_nil @adapter.entry('/invalid/invalid/') - ["README", "/README"].each do |path| - ["0", "0885933ad4f6", "0885933ad4f68d77c2649cd11f8311276e7ef7ce"].each do |rev| - entry = @adapter.entry(path, rev) - assert_equal "README", entry.path - assert_equal "file", entry.kind - assert_equal '0', entry.lastrev.revision - assert_equal '0885933ad4f68d77c2649cd11f8311276e7ef7ce', entry.lastrev.identifier - end + def test_entries_branch + entries1 = @adapter.entries(nil, 'test-branch-00') + assert entries1 + assert_equal 5, entries1.size + assert_equal 'sql_escape', entries1[2].name + assert_equal 'sql_escape', entries1[2].path + assert_equal 'dir', entries1[2].kind + readme = entries1[4] + assert_equal 'README', readme.name + assert_equal 'README', readme.path + assert_equal 'file', readme.kind + assert_equal 365, readme.size + assert_equal '8', readme.lastrev.revision + assert_equal 'c51f5bb613cd60793c2a9fe9df29332e74bb949f', readme.lastrev.identifier + # 2001-02-01 00:00:00 -0900 + assert_equal Time.gm(2001, 2, 1, 9, 0, 0), readme.lastrev.time + end + + def test_entry + entry = @adapter.entry() + assert_equal "", entry.path + assert_equal "dir", entry.kind + entry = @adapter.entry('') + assert_equal "", entry.path + assert_equal "dir", entry.kind + assert_nil @adapter.entry('invalid') + assert_nil @adapter.entry('/invalid') + assert_nil @adapter.entry('/invalid/') + assert_nil @adapter.entry('invalid/invalid') + assert_nil @adapter.entry('invalid/invalid/') + assert_nil @adapter.entry('/invalid/invalid') + assert_nil @adapter.entry('/invalid/invalid/') + ["README", "/README"].each do |path| + ["0", "0885933ad4f6", "0885933ad4f68d77c2649cd11f8311276e7ef7ce"].each do |rev| + entry = @adapter.entry(path, rev) + assert_equal "README", entry.path + assert_equal "file", entry.kind + assert_equal '0', entry.lastrev.revision + assert_equal '0885933ad4f68d77c2649cd11f8311276e7ef7ce', entry.lastrev.identifier end - ["sources", "/sources", "/sources/"].each do |path| - ["0", "0885933ad4f6", "0885933ad4f68d77c2649cd11f8311276e7ef7ce"].each do |rev| - entry = @adapter.entry(path, rev) - assert_equal "sources", entry.path - assert_equal "dir", entry.kind - end + end + ["sources", "/sources", "/sources/"].each do |path| + ["0", "0885933ad4f6", "0885933ad4f68d77c2649cd11f8311276e7ef7ce"].each do |rev| + entry = @adapter.entry(path, rev) + assert_equal "sources", entry.path + assert_equal "dir", entry.kind end - ["sources/watchers_controller.rb", "/sources/watchers_controller.rb"].each do |path| - ["0", "0885933ad4f6", "0885933ad4f68d77c2649cd11f8311276e7ef7ce"].each do |rev| - entry = @adapter.entry(path, rev) - assert_equal "sources/watchers_controller.rb", entry.path - assert_equal "file", entry.kind - assert_equal '0', entry.lastrev.revision - assert_equal '0885933ad4f68d77c2649cd11f8311276e7ef7ce', entry.lastrev.identifier - end + end + ["sources/watchers_controller.rb", "/sources/watchers_controller.rb"].each do |path| + ["0", "0885933ad4f6", "0885933ad4f68d77c2649cd11f8311276e7ef7ce"].each do |rev| + entry = @adapter.entry(path, rev) + assert_equal "sources/watchers_controller.rb", entry.path + assert_equal "file", entry.kind + assert_equal '0', entry.lastrev.revision + assert_equal '0885933ad4f68d77c2649cd11f8311276e7ef7ce', entry.lastrev.identifier end end + end - def test_locate_on_outdated_repository - assert_equal 1, @adapter.entries("images", 0).size - assert_equal 2, @adapter.entries("images").size - assert_equal 2, @adapter.entries("images", 2).size - end + def test_locate_on_outdated_repository + assert_equal 1, @adapter.entries("images", 0).size + assert_equal 2, @adapter.entries("images").size + assert_equal 2, @adapter.entries("images", 2).size + end - def test_access_by_nodeid - path = 'sources/welcome_controller.rb' - assert_equal @adapter.cat(path, 2), @adapter.cat(path, '400bb8672109') - end + def test_access_by_nodeid + path = 'sources/welcome_controller.rb' + assert_equal @adapter.cat(path, 2), @adapter.cat(path, '400bb8672109') + end - def test_access_by_fuzzy_nodeid - path = 'sources/welcome_controller.rb' - # falls back to nodeid - assert_equal @adapter.cat(path, 2), @adapter.cat(path, '400') - end + def test_access_by_fuzzy_nodeid + path = 'sources/welcome_controller.rb' + # falls back to nodeid + assert_equal @adapter.cat(path, 2), @adapter.cat(path, '400') + end - def test_tags - assert_equal [@tag_char_1, 'tag_test.00', 'tag-init-revision'], @adapter.tags - end + def test_tags + assert_equal [@tag_char_1, 'tag_test.00', 'tag-init-revision'], @adapter.tags + end - def test_tagmap - tm = { - @tag_char_1 => 'adf805632193500ad3b615cd04f58f9b0769f576', - 'tag_test.00' => '6987191f453a5f6557018d522feea2c450d5588d', - 'tag-init-revision' => '0885933ad4f68d77c2649cd11f8311276e7ef7ce', - } - assert_equal tm, @adapter.tagmap - end + def test_tagmap + tm = { + @tag_char_1 => 'adf805632193500ad3b615cd04f58f9b0769f576', + 'tag_test.00' => '6987191f453a5f6557018d522feea2c450d5588d', + 'tag-init-revision' => '0885933ad4f68d77c2649cd11f8311276e7ef7ce', + } + assert_equal tm, @adapter.tagmap + end - def test_branches - brs = [] - @adapter.branches.each do |b| - brs << b - end - assert_equal 7, brs.length - assert_equal 'default', brs[0].to_s - assert_equal '31', brs[0].revision - assert_equal '31eeee7395c8c78e66dd54c50addd078d10b2355', brs[0].scmid - assert_equal 'test-branch-01', brs[1].to_s - assert_equal '30', brs[1].revision - assert_equal 'ad4dc4f80284a4f9168b77e0b6de288e5d207ee7', brs[1].scmid - assert_equal @branch_char_1, brs[2].to_s - assert_equal '27', brs[2].revision - assert_equal '7bbf4c738e7145149d2e5eb1eed1d3a8ddd3b914', brs[2].scmid - assert_equal 'branch (1)[2]&,%.-3_4', brs[3].to_s - assert_equal '25', brs[3].revision - assert_equal 'afc61e85bde74de930e5846c8451bd55b5bafc9c', brs[3].scmid - assert_equal @branch_char_0, brs[4].to_s - assert_equal '23', brs[4].revision - assert_equal 'c8d3e4887474af6a589190140508037ebaa9d9c3', brs[4].scmid - assert_equal 'test_branch.latin-1', brs[5].to_s - assert_equal '22', brs[5].revision - assert_equal 'c2ffe7da686aa3d956e59f2a2854cf8980a8b768', brs[5].scmid - assert_equal 'test-branch-00', brs[6].to_s - assert_equal '13', brs[6].revision - assert_equal '3a330eb329586ea2adb3f83237c23310e744ebe9', brs[6].scmid + def test_branches + brs = [] + @adapter.branches.each do |b| + brs << b end + assert_equal 7, brs.length + assert_equal 'default', brs[0].to_s + assert_equal '31', brs[0].revision + assert_equal '31eeee7395c8c78e66dd54c50addd078d10b2355', brs[0].scmid + assert_equal 'test-branch-01', brs[1].to_s + assert_equal '30', brs[1].revision + assert_equal 'ad4dc4f80284a4f9168b77e0b6de288e5d207ee7', brs[1].scmid + assert_equal @branch_char_1, brs[2].to_s + assert_equal '27', brs[2].revision + assert_equal '7bbf4c738e7145149d2e5eb1eed1d3a8ddd3b914', brs[2].scmid + assert_equal 'branch (1)[2]&,%.-3_4', brs[3].to_s + assert_equal '25', brs[3].revision + assert_equal 'afc61e85bde74de930e5846c8451bd55b5bafc9c', brs[3].scmid + assert_equal @branch_char_0, brs[4].to_s + assert_equal '23', brs[4].revision + assert_equal 'c8d3e4887474af6a589190140508037ebaa9d9c3', brs[4].scmid + assert_equal 'test_branch.latin-1', brs[5].to_s + assert_equal '22', brs[5].revision + assert_equal 'c2ffe7da686aa3d956e59f2a2854cf8980a8b768', brs[5].scmid + assert_equal 'test-branch-00', brs[6].to_s + assert_equal '13', brs[6].revision + assert_equal '3a330eb329586ea2adb3f83237c23310e744ebe9', brs[6].scmid + end - def test_branchmap - bm = { - 'default' => '31eeee7395c8c78e66dd54c50addd078d10b2355', - 'test_branch.latin-1' => 'c2ffe7da686aa3d956e59f2a2854cf8980a8b768', - 'branch (1)[2]&,%.-3_4' => 'afc61e85bde74de930e5846c8451bd55b5bafc9c', - 'test-branch-00' => '3a330eb329586ea2adb3f83237c23310e744ebe9', - "test-branch-01" => 'ad4dc4f80284a4f9168b77e0b6de288e5d207ee7', - @branch_char_0 => 'c8d3e4887474af6a589190140508037ebaa9d9c3', - @branch_char_1 => '7bbf4c738e7145149d2e5eb1eed1d3a8ddd3b914', - } - assert_equal bm, @adapter.branchmap - end + def test_branchmap + bm = { + 'default' => '31eeee7395c8c78e66dd54c50addd078d10b2355', + 'test_branch.latin-1' => 'c2ffe7da686aa3d956e59f2a2854cf8980a8b768', + 'branch (1)[2]&,%.-3_4' => 'afc61e85bde74de930e5846c8451bd55b5bafc9c', + 'test-branch-00' => '3a330eb329586ea2adb3f83237c23310e744ebe9', + "test-branch-01" => 'ad4dc4f80284a4f9168b77e0b6de288e5d207ee7', + @branch_char_0 => 'c8d3e4887474af6a589190140508037ebaa9d9c3', + @branch_char_1 => '7bbf4c738e7145149d2e5eb1eed1d3a8ddd3b914', + } + assert_equal bm, @adapter.branchmap + end - def test_path_space - p = 'README (1)[2]&,%.-3_4' - [15, '933ca60293d7'].each do |r1| - assert @adapter.diff(p, r1) - assert @adapter.cat(p, r1) - assert_equal 1, @adapter.annotate(p, r1).lines.length - [25, 'afc61e85bde7'].each do |r2| - assert @adapter.diff(p, r1, r2) - end + def test_path_space + p = 'README (1)[2]&,%.-3_4' + [15, '933ca60293d7'].each do |r1| + assert @adapter.diff(p, r1) + assert @adapter.cat(p, r1) + assert_equal 1, @adapter.annotate(p, r1).lines.length + [25, 'afc61e85bde7'].each do |r2| + assert @adapter.diff(p, r1, r2) end end + end - def test_tag_non_ascii - p = "latin-1-dir/test-#{@char_1}-1.txt" - assert @adapter.cat(p, @tag_char_1) - assert_equal 1, @adapter.annotate(p, @tag_char_1).lines.length - end + def test_tag_non_ascii + p = "latin-1-dir/test-#{@char_1}-1.txt" + assert @adapter.cat(p, @tag_char_1) + assert_equal 1, @adapter.annotate(p, @tag_char_1).lines.length + end - def test_branch_non_ascii - p = "latin-1-dir/test-#{@char_1}-subdir/test-#{@char_1}-1.txt" - assert @adapter.cat(p, @branch_char_1) - assert_equal 1, @adapter.annotate(p, @branch_char_1).lines.length - end + def test_branch_non_ascii + p = "latin-1-dir/test-#{@char_1}-subdir/test-#{@char_1}-1.txt" + assert @adapter.cat(p, @branch_char_1) + assert_equal 1, @adapter.annotate(p, @branch_char_1).lines.length + end - def test_nodes_in_branch - [ - 'default', - @branch_char_1, - 'branch (1)[2]&,%.-3_4', - @branch_char_0, - 'test_branch.latin-1', - 'test-branch-00', - ].each do |bra| - nib0 = @adapter.nodes_in_branch(bra) - assert nib0 - nib1 = @adapter.nodes_in_branch(bra, :limit => 1) - assert_equal 1, nib1.size - case bra - when 'branch (1)[2]&,%.-3_4' - if @adapter.class.client_version_above?([1, 6]) - assert_equal 3, nib0.size - assert_equal 'afc61e85bde74de930e5846c8451bd55b5bafc9c', nib0[0] - nib2 = @adapter.nodes_in_branch(bra, :limit => 2) - assert_equal 2, nib2.size - assert_equal '933ca60293d78f7c7979dd123cc0c02431683575', nib2[1] - end - when @branch_char_1 - if @adapter.class.client_version_above?([1, 6]) - assert_equal 2, nib0.size - assert_equal '08ff3227303ec0dfcc818efa8e9cc652fe81859f', nib0[1] - nib2 = @adapter.nodes_in_branch(bra, :limit => 1) - assert_equal 1, nib2.size - assert_equal '7bbf4c738e7145149d2e5eb1eed1d3a8ddd3b914', nib2[0] - end - end + def test_nodes_in_branch + [ + 'default', + @branch_char_1, + 'branch (1)[2]&,%.-3_4', + @branch_char_0, + 'test_branch.latin-1', + 'test-branch-00', + ].each do |bra| + nib0 = @adapter.nodes_in_branch(bra) + assert nib0 + nib1 = @adapter.nodes_in_branch(bra, :limit => 1) + assert_equal 1, nib1.size + case bra + when 'branch (1)[2]&,%.-3_4' + if @adapter.class.client_version_above?([1, 6]) + assert_equal 3, nib0.size + assert_equal 'afc61e85bde74de930e5846c8451bd55b5bafc9c', nib0[0] + nib2 = @adapter.nodes_in_branch(bra, :limit => 2) + assert_equal 2, nib2.size + assert_equal '933ca60293d78f7c7979dd123cc0c02431683575', nib2[1] + end + when @branch_char_1 + if @adapter.class.client_version_above?([1, 6]) + assert_equal 2, nib0.size + assert_equal '08ff3227303ec0dfcc818efa8e9cc652fe81859f', nib0[1] + nib2 = @adapter.nodes_in_branch(bra, :limit => 1) + assert_equal 1, nib2.size + assert_equal '7bbf4c738e7145149d2e5eb1eed1d3a8ddd3b914', nib2[0] + end end end + end - def test_path_encoding_default_utf8 - adpt1 = Redmine::Scm::Adapters::MercurialAdapter.new( - REPOSITORY_PATH - ) - assert_equal "UTF-8", adpt1.path_encoding - adpt2 = Redmine::Scm::Adapters::MercurialAdapter.new( - REPOSITORY_PATH, - nil, - nil, - nil, - "" - ) - assert_equal "UTF-8", adpt2.path_encoding - end + def test_path_encoding_default_utf8 + adpt1 = Redmine::Scm::Adapters::MercurialAdapter.new( + REPOSITORY_PATH + ) + assert_equal "UTF-8", adpt1.path_encoding + adpt2 = Redmine::Scm::Adapters::MercurialAdapter.new( + REPOSITORY_PATH, + nil, + nil, + nil, + "" + ) + assert_equal "UTF-8", adpt2.path_encoding + end - private + private - def test_hgversion_for(hgversion, version) - @adapter.class.expects(:hgversion_from_command_line).returns(hgversion) - assert_equal version, @adapter.class.hgversion - end + def test_hgversion_for(hgversion, version) + @adapter.class.expects(:hgversion_from_command_line).returns(hgversion) + assert_equal version, @adapter.class.hgversion + end - def test_template_path_for(version, template) - assert_equal "#{HELPERS_DIR}/#{TEMPLATE_NAME}-#{template}.#{TEMPLATE_EXTENSION}", - @adapter.class.template_path_for(version) - assert File.exist?(@adapter.class.template_path_for(version)) - end - else - puts "Mercurial test repository NOT FOUND. Skipping unit tests !!!" - def test_fake; assert true end + def test_template_path_for(version, template) + assert_equal "#{HELPERS_DIR}/#{TEMPLATE_NAME}-#{template}.#{TEMPLATE_EXTENSION}", + @adapter.class.template_path_for(version) + assert File.exist?(@adapter.class.template_path_for(version)) end - end -rescue LoadError - class MercurialMochaFake < ActiveSupport::TestCase - def test_fake; assert(false, "Requires mocha to run those tests") end + else + puts "Mercurial test repository NOT FOUND. Skipping unit tests !!!" + def test_fake; assert true end end end diff --git a/test/unit/lib/redmine/scm/adapters/subversion_adapter_test.rb b/test/unit/lib/redmine/scm/adapters/subversion_adapter_test.rb index f272c0a0e..161f7d2e7 100644 --- a/test/unit/lib/redmine/scm/adapters/subversion_adapter_test.rb +++ b/test/unit/lib/redmine/scm/adapters/subversion_adapter_test.rb @@ -17,55 +17,47 @@ require File.expand_path('../../../../../../test_helper', __FILE__) -begin - require 'mocha/setup' +class SubversionAdapterTest < ActiveSupport::TestCase - class SubversionAdapterTest < ActiveSupport::TestCase - - if repository_configured?('subversion') - def setup - @adapter = Redmine::Scm::Adapters::SubversionAdapter.new(self.class.subversion_repository_url) - end + if repository_configured?('subversion') + def setup + @adapter = Redmine::Scm::Adapters::SubversionAdapter.new(self.class.subversion_repository_url) + end - def test_client_version - v = Redmine::Scm::Adapters::SubversionAdapter.client_version - assert v.is_a?(Array) - end + def test_client_version + v = Redmine::Scm::Adapters::SubversionAdapter.client_version + assert v.is_a?(Array) + end - def test_scm_version - to_test = { "svn, version 1.6.13 (r1002816)\n" => [1,6,13], - "svn, versione 1.6.13 (r1002816)\n" => [1,6,13], - "1.6.1\n1.7\n1.8" => [1,6,1], - "1.6.2\r\n1.8.1\r\n1.9.1" => [1,6,2]} - to_test.each do |s, v| - test_scm_version_for(s, v) - end + def test_scm_version + to_test = { "svn, version 1.6.13 (r1002816)\n" => [1,6,13], + "svn, versione 1.6.13 (r1002816)\n" => [1,6,13], + "1.6.1\n1.7\n1.8" => [1,6,1], + "1.6.2\r\n1.8.1\r\n1.9.1" => [1,6,2]} + to_test.each do |s, v| + test_scm_version_for(s, v) end + end - def test_info_not_nil - assert_not_nil @adapter.info - end + def test_info_not_nil + assert_not_nil @adapter.info + end - def test_info_nil - adpt = Redmine::Scm::Adapters::SubversionAdapter.new( - "file:///invalid/invalid/" - ) - assert_nil adpt.info - end + def test_info_nil + adpt = Redmine::Scm::Adapters::SubversionAdapter.new( + "file:///invalid/invalid/" + ) + assert_nil adpt.info + end - private + private - def test_scm_version_for(scm_version, version) - @adapter.class.expects(:scm_version_from_command_line).returns(scm_version) - assert_equal version, @adapter.class.svn_binary_version - end - else - puts "Subversion test repository NOT FOUND. Skipping unit tests !!!" - def test_fake; assert true end + def test_scm_version_for(scm_version, version) + @adapter.class.expects(:scm_version_from_command_line).returns(scm_version) + assert_equal version, @adapter.class.svn_binary_version end - end -rescue LoadError - class SubversionMochaFake < ActiveSupport::TestCase - def test_fake; assert(false, "Requires mocha to run those tests") end + else + puts "Subversion test repository NOT FOUND. Skipping unit tests !!!" + def test_fake; assert true end end end diff --git a/test/unit/lib/redmine/unified_diff_test.rb b/test/unit/lib/redmine/unified_diff_test.rb index 4956e52f6..e3130fd28 100644 --- a/test/unit/lib/redmine/unified_diff_test.rb +++ b/test/unit/lib/redmine/unified_diff_test.rb @@ -223,8 +223,7 @@ DIFF def test_utf8_ja ja = " text_tip_issue_end_day: " - ja += "\xe3\x81\x93\xe3\x81\xae\xe6\x97\xa5\xe3\x81\xab\xe7\xb5\x82\xe4\xba\x86\xe3\x81\x99\xe3\x82\x8b<span>\xe3\x82\xbf\xe3\x82\xb9\xe3\x82\xaf</span>" - ja.force_encoding('UTF-8') if ja.respond_to?(:force_encoding) + ja += "\xe3\x81\x93\xe3\x81\xae\xe6\x97\xa5\xe3\x81\xab\xe7\xb5\x82\xe4\xba\x86\xe3\x81\x99\xe3\x82\x8b<span>\xe3\x82\xbf\xe3\x82\xb9\xe3\x82\xaf</span>".force_encoding('UTF-8') with_settings :repositories_encodings => '' do diff = Redmine::UnifiedDiff.new(read_diff_fixture('issue-12641-ja.diff'), :type => 'inline') assert_equal 1, diff.size @@ -234,8 +233,7 @@ DIFF end def test_utf8_ru - ru = " other: "\xd0\xbe\xd0\xba\xd0\xbe\xd0\xbb\xd0\xbe %{count} \xd1\x87\xd0\xb0\xd1\x81<span>\xd0\xb0</span>"" - ru.force_encoding('UTF-8') if ru.respond_to?(:force_encoding) + ru = " other: "\xd0\xbe\xd0\xba\xd0\xbe\xd0\xbb\xd0\xbe %{count} \xd1\x87\xd0\xb0\xd1\x81<span>\xd0\xb0</span>"".force_encoding('UTF-8') with_settings :repositories_encodings => '' do diff = Redmine::UnifiedDiff.new(read_diff_fixture('issue-12641-ru.diff'), :type => 'inline') assert_equal 1, diff.size @@ -279,10 +277,8 @@ DIFF end def test_offset_range_japanese_1 - ja1 = "\xe6\x97\xa5\xe6\x9c\xac<span></span>" - ja1.force_encoding('UTF-8') if ja1.respond_to?(:force_encoding) - ja2 = "\xe6\x97\xa5\xe6\x9c\xac<span>\xe8\xaa\x9e</span>" - ja2.force_encoding('UTF-8') if ja2.respond_to?(:force_encoding) + ja1 = "\xe6\x97\xa5\xe6\x9c\xac<span></span>".force_encoding('UTF-8') + ja2 = "\xe6\x97\xa5\xe6\x9c\xac<span>\xe8\xaa\x9e</span>".force_encoding('UTF-8') with_settings :repositories_encodings => '' do diff = Redmine::UnifiedDiff.new( read_diff_fixture('issue-13644-1.diff'), :type => 'sbs') @@ -294,10 +290,8 @@ DIFF end def test_offset_range_japanese_2 - ja1 = "<span></span>\xe6\x97\xa5\xe6\x9c\xac" - ja1.force_encoding('UTF-8') if ja1.respond_to?(:force_encoding) - ja2 = "<span>\xe3\x81\xab\xe3\x81\xa3\xe3\x81\xbd\xe3\x82\x93</span>\xe6\x97\xa5\xe6\x9c\xac" - ja2.force_encoding('UTF-8') if ja2.respond_to?(:force_encoding) + ja1 = "<span></span>\xe6\x97\xa5\xe6\x9c\xac".force_encoding('UTF-8') + ja2 = "<span>\xe3\x81\xab\xe3\x81\xa3\xe3\x81\xbd\xe3\x82\x93</span>\xe6\x97\xa5\xe6\x9c\xac".force_encoding('UTF-8') with_settings :repositories_encodings => '' do diff = Redmine::UnifiedDiff.new( read_diff_fixture('issue-13644-2.diff'), :type => 'sbs') @@ -310,10 +304,8 @@ DIFF def test_offset_range_japanese_3 # UTF-8 The 1st byte differs. - ja1 = "\xe6\x97\xa5\xe6\x9c\xac<span>\xe8\xa8\x98</span>" - ja1.force_encoding('UTF-8') if ja1.respond_to?(:force_encoding) - ja2 = "\xe6\x97\xa5\xe6\x9c\xac<span>\xe5\xa8\x98</span>" - ja2.force_encoding('UTF-8') if ja2.respond_to?(:force_encoding) + ja1 = "\xe6\x97\xa5\xe6\x9c\xac<span>\xe8\xa8\x98</span>".force_encoding('UTF-8') + ja2 = "\xe6\x97\xa5\xe6\x9c\xac<span>\xe5\xa8\x98</span>".force_encoding('UTF-8') with_settings :repositories_encodings => '' do diff = Redmine::UnifiedDiff.new( read_diff_fixture('issue-13644-3.diff'), :type => 'sbs') @@ -326,10 +318,8 @@ DIFF def test_offset_range_japanese_4 # UTF-8 The 2nd byte differs. - ja1 = "\xe6\x97\xa5\xe6\x9c\xac<span>\xe8\xa8\x98</span>" - ja1.force_encoding('UTF-8') if ja1.respond_to?(:force_encoding) - ja2 = "\xe6\x97\xa5\xe6\x9c\xac<span>\xe8\xaa\x98</span>" - ja2.force_encoding('UTF-8') if ja2.respond_to?(:force_encoding) + ja1 = "\xe6\x97\xa5\xe6\x9c\xac<span>\xe8\xa8\x98</span>".force_encoding('UTF-8') + ja2 = "\xe6\x97\xa5\xe6\x9c\xac<span>\xe8\xaa\x98</span>".force_encoding('UTF-8') with_settings :repositories_encodings => '' do diff = Redmine::UnifiedDiff.new( read_diff_fixture('issue-13644-4.diff'), :type => 'sbs') @@ -342,10 +332,8 @@ DIFF def test_offset_range_japanese_5 # UTF-8 The 2nd byte differs. - ja1 = "\xe6\x97\xa5\xe6\x9c\xac<span>\xe8\xa8\x98</span>ok" - ja1.force_encoding('UTF-8') if ja1.respond_to?(:force_encoding) - ja2 = "\xe6\x97\xa5\xe6\x9c\xac<span>\xe8\xaa\x98</span>ok" - ja2.force_encoding('UTF-8') if ja2.respond_to?(:force_encoding) + ja1 = "\xe6\x97\xa5\xe6\x9c\xac<span>\xe8\xa8\x98</span>ok".force_encoding('UTF-8') + ja2 = "\xe6\x97\xa5\xe6\x9c\xac<span>\xe8\xaa\x98</span>ok".force_encoding('UTF-8') with_settings :repositories_encodings => '' do diff = Redmine::UnifiedDiff.new( read_diff_fixture('issue-13644-5.diff'), :type => 'sbs') diff --git a/test/unit/lib/redmine/wiki_formatting/macros_test.rb b/test/unit/lib/redmine/wiki_formatting/macros_test.rb index 7f5308d1b..8c218849d 100644 --- a/test/unit/lib/redmine/wiki_formatting/macros_test.rb +++ b/test/unit/lib/redmine/wiki_formatting/macros_test.rb @@ -207,12 +207,14 @@ class Redmine::WikiFormatting::MacrosTest < ActionView::TestCase def test_macro_collapse text = "{{collapse\n*Collapsed* block of text\n}}" - result = textilizable(text) - - assert_select_in result, 'div.collapsed-text' - assert_select_in result, 'strong', :text => 'Collapsed' - assert_select_in result, 'a.collapsible.collapsed', :text => 'Show' - assert_select_in result, 'a.collapsible', :text => 'Hide' + with_locale 'en' do + result = textilizable(text) + + assert_select_in result, 'div.collapsed-text' + assert_select_in result, 'strong', :text => 'Collapsed' + assert_select_in result, 'a.collapsible.collapsed', :text => 'Show' + assert_select_in result, 'a.collapsible', :text => 'Hide' + end end def test_macro_collapse_with_one_arg diff --git a/test/unit/mail_handler_test.rb b/test/unit/mail_handler_test.rb index 1a3469031..bb91ac3f7 100644 --- a/test/unit/mail_handler_test.rb +++ b/test/unit/mail_handler_test.rb @@ -411,8 +411,7 @@ class MailHandlerTest < ActiveSupport::TestCase end def test_add_issue_with_japanese_keywords - ja_dev = "\xe9\x96\x8b\xe7\x99\xba" - ja_dev.force_encoding('UTF-8') if ja_dev.respond_to?(:force_encoding) + ja_dev = "\xe9\x96\x8b\xe7\x99\xba".force_encoding('UTF-8') tracker = Tracker.create!(:name => ja_dev) Project.find(1).trackers << tracker issue = submit_email( @@ -447,8 +446,7 @@ class MailHandlerTest < ActiveSupport::TestCase ) assert_kind_of Issue, issue assert_equal 1, issue.attachments.size - ja = "\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88.txt" - ja.force_encoding('UTF-8') if ja.respond_to?(:force_encoding) + ja = "\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88.txt".force_encoding('UTF-8') attachment = issue.attachments.first assert_equal ja, attachment.filename assert_equal 5, attachment.filesize @@ -464,8 +462,7 @@ class MailHandlerTest < ActiveSupport::TestCase ) assert_kind_of Issue, issue assert_equal 1, issue.attachments.size - ja = "\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88.txt" - ja.force_encoding('UTF-8') if ja.respond_to?(:force_encoding) + ja = "\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88.txt".force_encoding('UTF-8') attachment = issue.attachments.first assert_equal ja, attachment.filename assert_equal 5, attachment.filesize @@ -481,10 +478,8 @@ class MailHandlerTest < ActiveSupport::TestCase ) assert_kind_of Issue, issue assert_equal 1, issue.attachments.size - u = "" - u.force_encoding('UTF-8') if u.respond_to?(:force_encoding) - u1 = "\xc3\x84\xc3\xa4\xc3\x96\xc3\xb6\xc3\x9c\xc3\xbc" - u1.force_encoding('UTF-8') if u1.respond_to?(:force_encoding) + u = "".force_encoding('UTF-8') + u1 = "\xc3\x84\xc3\xa4\xc3\x96\xc3\xb6\xc3\x9c\xc3\xbc".force_encoding('UTF-8') 11.times { u << u1 } attachment = issue.attachments.first assert_equal "#{u}.png", attachment.filename @@ -501,10 +496,8 @@ class MailHandlerTest < ActiveSupport::TestCase ) assert_kind_of Issue, issue assert_equal 1, issue.attachments.size - u = "" - u.force_encoding('UTF-8') if u.respond_to?(:force_encoding) - u1 = "\xc3\x84\xc3\xa4\xc3\x96\xc3\xb6\xc3\x9c\xc3\xbc" - u1.force_encoding('UTF-8') if u1.respond_to?(:force_encoding) + u = "".force_encoding('UTF-8') + u1 = "\xc3\x84\xc3\xa4\xc3\x96\xc3\xb6\xc3\x9c\xc3\xbc".force_encoding('UTF-8') 11.times { u << u1 } attachment = issue.attachments.first assert_equal "#{u}.txt", attachment.filename @@ -534,8 +527,7 @@ class MailHandlerTest < ActiveSupport::TestCase 'subject_as_iso-8859-1.eml', :issue => {:project => 'ecookbook'} ) - str = "Testmail from Webmail: \xc3\xa4 \xc3\xb6 \xc3\xbc..." - str.force_encoding('UTF-8') if str.respond_to?(:force_encoding) + str = "Testmail from Webmail: \xc3\xa4 \xc3\xb6 \xc3\xbc...".force_encoding('UTF-8') assert_kind_of Issue, issue assert_equal str, issue.subject end @@ -546,8 +538,7 @@ class MailHandlerTest < ActiveSupport::TestCase :issue => {:project => 'ecookbook'} ) assert_kind_of Issue, issue - str = "Freundliche Gr\xc3\xbcsse" - str.force_encoding('UTF-8') if str.respond_to?(:force_encoding) + str = "Freundliche Gr\xc3\xbcsse".force_encoding('UTF-8') assert_equal str, issue.description end @@ -557,8 +548,7 @@ class MailHandlerTest < ActiveSupport::TestCase :issue => {:project => 'ecookbook'} ) assert_kind_of Issue, issue - str = "Na \xc5\xa1triku se su\xc5\xa1i \xc5\xa1osi\xc4\x87." - str.force_encoding('UTF-8') if str.respond_to?(:force_encoding) + str = "Na \xc5\xa1triku se su\xc5\xa1i \xc5\xa1osi\xc4\x87.".force_encoding('UTF-8') assert issue.description.include?(str) end @@ -568,26 +558,20 @@ class MailHandlerTest < ActiveSupport::TestCase :issue => {:project => 'ecookbook'} ) assert_kind_of Issue, issue - ja = "\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88" - ja.force_encoding('UTF-8') if ja.respond_to?(:force_encoding) + ja = "\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88".force_encoding('UTF-8') assert_equal ja, issue.subject end def test_add_issue_with_korean_body # Make sure mail bodies with a charset unknown to Ruby # but known to the Mail gem 2.5.4 are handled correctly - kr = "\xEA\xB3\xA0\xEB\xA7\x99\xEC\x8A\xB5\xEB\x8B\x88\xEB\x8B\xA4." - if !kr.respond_to?(:force_encoding) - puts "\nOn Ruby 1.8, skip Korean encoding mail body test" - else - kr.force_encoding('UTF-8') - issue = submit_email( - 'body_ks_c_5601-1987.eml', - :issue => {:project => 'ecookbook'} - ) - assert_kind_of Issue, issue - assert_equal kr, issue.description - end + kr = "\xEA\xB3\xA0\xEB\xA7\x99\xEC\x8A\xB5\xEB\x8B\x88\xEB\x8B\xA4.".force_encoding('UTF-8') + issue = submit_email( + 'body_ks_c_5601-1987.eml', + :issue => {:project => 'ecookbook'} + ) + assert_kind_of Issue, issue + assert_equal kr, issue.description end def test_add_issue_with_no_subject_header @@ -605,8 +589,7 @@ class MailHandlerTest < ActiveSupport::TestCase :issue => {:project => 'ecookbook'} ) assert_kind_of Issue, issue - ja = "Re: \xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88" - ja.force_encoding('UTF-8') if ja.respond_to?(:force_encoding) + ja = "Re: \xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88".force_encoding('UTF-8') assert_equal ja, issue.subject end @@ -910,10 +893,8 @@ class MailHandlerTest < ActiveSupport::TestCase end user = User.order('id DESC').first assert_equal "foo@example.org", user.mail - str1 = "\xc3\x84\xc3\xa4" - str2 = "\xc3\x96\xc3\xb6" - str1.force_encoding('UTF-8') if str1.respond_to?(:force_encoding) - str2.force_encoding('UTF-8') if str2.respond_to?(:force_encoding) + str1 = "\xc3\x84\xc3\xa4".force_encoding('UTF-8') + str2 = "\xc3\x96\xc3\xb6".force_encoding('UTF-8') assert_equal str1, user.firstname assert_equal str2, user.lastname end diff --git a/test/unit/mailer_test.rb b/test/unit/mailer_test.rb index 983e9fc4f..b3678ebb5 100644 --- a/test/unit/mailer_test.rb +++ b/test/unit/mailer_test.rb @@ -34,6 +34,7 @@ class MailerTest < ActiveSupport::TestCase Setting.host_name = 'mydomain.foo' Setting.protocol = 'http' Setting.plain_text_mail = '0' + User.current = nil end def test_generated_links_in_emails diff --git a/test/unit/member_test.rb b/test/unit/member_test.rb index 124aa3719..f45824ce9 100644 --- a/test/unit/member_test.rb +++ b/test/unit/member_test.rb @@ -79,9 +79,8 @@ class MemberTest < ActiveSupport::TestCase member = Member.new(:project_id => 1, :user_id => user.id, :role_ids => []) assert !member.save assert_include I18n.translate('activerecord.errors.messages.empty'), member.errors[:role] - str = "R\xc3\xb4le doit \xc3\xaatre renseign\xc3\xa9(e)" - str.force_encoding('UTF-8') if str.respond_to?(:force_encoding) - assert_equal str, [member.errors.full_messages].flatten.join + assert_equal "R\xc3\xb4le doit \xc3\xaatre renseign\xc3\xa9(e)".force_encoding('UTF-8'), + [member.errors.full_messages].flatten.join end def test_validate_member_role @@ -131,7 +130,7 @@ class MemberTest < ActiveSupport::TestCase end assert m.destroyed? ensure - Member._destroy_callbacks.reject! {|c| c.filter==:destroy_test_callback} + Member._destroy_callbacks.delete(:destroy_test_callback) end def test_sort_without_roles diff --git a/test/unit/principal_test.rb b/test/unit/principal_test.rb index b37f781a3..3b599c373 100644 --- a/test/unit/principal_test.rb +++ b/test/unit/principal_test.rb @@ -23,7 +23,7 @@ class PrincipalTest < ActiveSupport::TestCase fixtures :users, :projects, :members, :member_roles def test_active_scope_should_return_groups_and_active_users - result = Principal.active.all + result = Principal.active.to_a assert_include Group.first, result assert_not_nil result.detect {|p| p.is_a?(User)} assert_nil result.detect {|p| p.is_a?(User) && !p.active?} diff --git a/test/unit/project_copy_test.rb b/test/unit/project_copy_test.rb index 2f1f6ee59..238417a2d 100644 --- a/test/unit/project_copy_test.rb +++ b/test/unit/project_copy_test.rb @@ -222,17 +222,6 @@ class ProjectCopyTest < ActiveSupport::TestCase assert_equal @source_project.queries.map(&:user_id).sort, @project.queries.map(&:user_id).sort end - def test_copy_should_copy_queries_roles_visibility - source = Project.generate! - target = Project.new(:name => 'Copy Test', :identifier => 'copy-test') - IssueQuery.generate!(:project => source, :visibility => Query::VISIBILITY_ROLES, :roles => Role.where(:id => [1, 3]).to_a) - - assert target.copy(source) - assert_equal 1, target.queries.size - query = target.queries.first - assert_equal [1, 3], query.role_ids.sort - end - test "#copy should copy versions" do @source_project.versions << Version.generate! @source_project.versions << Version.generate! diff --git a/test/unit/project_nested_set_test.rb b/test/unit/project_nested_set_test.rb index 43c55dff8..3ecd78512 100644 --- a/test/unit/project_nested_set_test.rb +++ b/test/unit/project_nested_set_test.rb @@ -61,6 +61,11 @@ class ProjectNestedSetTest < ActiveSupport::TestCase assert_valid_nested_set end + def test_rebuild_without_projects_should_not_fail + Project.delete_all + assert Project.rebuild_tree! + end + def test_moving_a_child_to_a_different_parent_should_keep_valid_tree assert_no_difference 'Project.count' do Project.find_by_name('B1').set_parent!(Project.find_by_name('A2')) diff --git a/test/unit/project_test.rb b/test/unit/project_test.rb index 0dc3a54f1..ff859b6f3 100644 --- a/test/unit/project_test.rb +++ b/test/unit/project_test.rb @@ -316,7 +316,7 @@ class ProjectTest < ActiveSupport::TestCase parent.reload assert_equal 4, parent.children.size - assert_equal parent.children.all.sort_by(&:name), parent.children.all + assert_equal parent.children.sort_by(&:name), parent.children.to_a end def test_set_parent_should_update_issue_fixed_version_associations_when_a_fixed_version_is_moved_out_of_the_hierarchy @@ -729,7 +729,7 @@ class ProjectTest < ActiveSupport::TestCase def test_activities_should_use_the_system_activities project = Project.find(1) - assert_equal project.activities, TimeEntryActivity.where(:active => true).all + assert_equal project.activities.to_a, TimeEntryActivity.where(:active => true).to_a assert_kind_of ActiveRecord::Relation, project.activities end @@ -944,4 +944,10 @@ class ProjectTest < ActiveSupport::TestCase assert !project.notified_users.include?(only_assigned_user), "should not include users with the 'only_assigned' notification option" assert !project.notified_users.include?(only_owned_user), "should not include users with the 'only_owner' notification option" end + + def test_override_roles_without_builtin_group_memberships + project = Project.generate! + assert_equal [Role.anonymous], project.override_roles(Role.anonymous) + assert_equal [Role.non_member], project.override_roles(Role.non_member) + end end diff --git a/test/unit/query_test.rb b/test/unit/query_test.rb index 102efd4de..692fbdbbe 100644 --- a/test/unit/query_test.rb +++ b/test/unit/query_test.rb @@ -101,9 +101,9 @@ class QueryTest < ActiveSupport::TestCase end def find_issues_with_query(query) - Issue.includes([:assigned_to, :status, :tracker, :project, :priority]).where( + Issue.joins(:status, :tracker, :project, :priority).where( query.statement - ).all + ).references([:assigned_to, :status, :tracker, :project, :priority]).to_a end def assert_find_issues_with_query_is_successful(query) @@ -1118,9 +1118,7 @@ class QueryTest < ActiveSupport::TestCase def test_label_for_fr set_language_if_valid 'fr' q = IssueQuery.new - s = "Assign\xc3\xa9 \xc3\xa0" - s.force_encoding('UTF-8') if s.respond_to?(:force_encoding) - assert_equal s, q.label_for('assigned_to_id') + assert_equal "Assign\xc3\xa9 \xc3\xa0".force_encoding('UTF-8'), q.label_for('assigned_to_id') end def test_editable_by diff --git a/test/unit/repository_bazaar_test.rb b/test/unit/repository_bazaar_test.rb index 3e15958c0..da2103797 100644 --- a/test/unit/repository_bazaar_test.rb +++ b/test/unit/repository_bazaar_test.rb @@ -22,7 +22,7 @@ class RepositoryBazaarTest < ActiveSupport::TestCase include Redmine::I18n - REPOSITORY_PATH = Rails.root.join('tmp/test/bazaar_repository').to_s + REPOSITORY_PATH = repository_path('bazaar') REPOSITORY_PATH_TRUNK = File.join(REPOSITORY_PATH, "trunk") NUM_REV = 4 @@ -42,11 +42,10 @@ class RepositoryBazaarTest < ActiveSupport::TestCase # you cannot run Bazaar non ASCII path tests. # RUN_LATIN1_OUTPUT_TEST = (RUBY_PLATFORM != 'java' && - REPOSITORY_PATH.respond_to?(:force_encoding) && Encoding.locale_charmap == "ISO-8859-1") - CHAR_1_UTF8_HEX = "\xc3\x9c" - CHAR_1_LATIN1_HEX = "\xdc" + CHAR_1_UTF8_HEX = "\xc3\x9c".force_encoding('UTF-8') + CHAR_1_LATIN1_HEX = "\xdc".force_encoding('ASCII-8BIT') def setup @project = Project.find(3) @@ -54,12 +53,6 @@ class RepositoryBazaarTest < ActiveSupport::TestCase :project => @project, :url => REPOSITORY_PATH_TRUNK, :log_encoding => 'UTF-8') assert @repository - @char_1_utf8 = CHAR_1_UTF8_HEX.dup - @char_1_ascii8bit = CHAR_1_LATIN1_HEX.dup - if @char_1_utf8.respond_to?(:force_encoding) - @char_1_utf8.force_encoding('UTF-8') - @char_1_ascii8bit.force_encoding('ASCII-8BIT') - end end def test_blank_path_to_repository_error_message @@ -76,8 +69,7 @@ class RepositoryBazaarTest < ActiveSupport::TestCase def test_blank_path_to_repository_error_message_fr set_language_if_valid 'fr' - str = "Chemin du d\xc3\xa9p\xc3\xb4t doit \xc3\xaatre renseign\xc3\xa9(e)" - str.force_encoding('UTF-8') if str.respond_to?(:force_encoding) + str = "Chemin du d\xc3\xa9p\xc3\xb4t doit \xc3\xaatre renseign\xc3\xa9(e)".force_encoding('UTF-8') repo = Repository::Bazaar.new( :project => @project, :url => "", @@ -178,70 +170,70 @@ class RepositoryBazaarTest < ActiveSupport::TestCase def test_cat_latin1_path latin1_repo = create_latin1_repo buf = latin1_repo.cat( - "test-#{@char_1_utf8}-dir/test-#{@char_1_utf8}-2.txt", 2) + "test-#{CHAR_1_UTF8_HEX}-dir/test-#{CHAR_1_UTF8_HEX}-2.txt", 2) assert buf lines = buf.split("\n") assert_equal 2, lines.length assert_equal 'It is written in Python.', lines[1] buf = latin1_repo.cat( - "test-#{@char_1_utf8}-dir/test-#{@char_1_utf8}-1.txt", 2) + "test-#{CHAR_1_UTF8_HEX}-dir/test-#{CHAR_1_UTF8_HEX}-1.txt", 2) assert buf lines = buf.split("\n") assert_equal 1, lines.length - assert_equal "test-#{@char_1_ascii8bit}.txt", lines[0] + assert_equal "test-#{CHAR_1_LATIN1_HEX}.txt", lines[0] end def test_annotate_latin1_path latin1_repo = create_latin1_repo ann1 = latin1_repo.annotate( - "test-#{@char_1_utf8}-dir/test-#{@char_1_utf8}-2.txt", 2) + "test-#{CHAR_1_UTF8_HEX}-dir/test-#{CHAR_1_UTF8_HEX}-2.txt", 2) assert_equal 2, ann1.lines.size assert_equal '2', ann1.revisions[0].identifier assert_equal 'test00@', ann1.revisions[0].author assert_equal 'It is written in Python.', ann1.lines[1] ann2 = latin1_repo.annotate( - "test-#{@char_1_utf8}-dir/test-#{@char_1_utf8}-1.txt", 2) + "test-#{CHAR_1_UTF8_HEX}-dir/test-#{CHAR_1_UTF8_HEX}-1.txt", 2) assert_equal 1, ann2.lines.size assert_equal '2', ann2.revisions[0].identifier assert_equal 'test00@', ann2.revisions[0].author - assert_equal "test-#{@char_1_ascii8bit}.txt", ann2.lines[0] + assert_equal "test-#{CHAR_1_LATIN1_HEX}.txt", ann2.lines[0] end def test_diff_latin1_path latin1_repo = create_latin1_repo diff1 = latin1_repo.diff( - "test-#{@char_1_utf8}-dir/test-#{@char_1_utf8}-1.txt", 2, 1) + "test-#{CHAR_1_UTF8_HEX}-dir/test-#{CHAR_1_UTF8_HEX}-1.txt", 2, 1) assert_equal 7, diff1.size buf = diff1[5].gsub(/\r\n|\r|\n/, "") - assert_equal "+test-#{@char_1_ascii8bit}.txt", buf + assert_equal "+test-#{CHAR_1_LATIN1_HEX}.txt", buf end def test_entries_latin1_path latin1_repo = create_latin1_repo - entries = latin1_repo.entries("test-#{@char_1_utf8}-dir", 2) + entries = latin1_repo.entries("test-#{CHAR_1_UTF8_HEX}-dir", 2) assert_kind_of Redmine::Scm::Adapters::Entries, entries assert_equal 3, entries.size assert_equal 'file', entries[1].kind - assert_equal "test-#{@char_1_utf8}-1.txt", entries[0].name - assert_equal "test-#{@char_1_utf8}-dir/test-#{@char_1_utf8}-1.txt", entries[0].path + assert_equal "test-#{CHAR_1_UTF8_HEX}-1.txt", entries[0].name + assert_equal "test-#{CHAR_1_UTF8_HEX}-dir/test-#{CHAR_1_UTF8_HEX}-1.txt", entries[0].path end def test_entry_latin1_path latin1_repo = create_latin1_repo - ["test-#{@char_1_utf8}-dir", - "/test-#{@char_1_utf8}-dir", - "/test-#{@char_1_utf8}-dir/" + ["test-#{CHAR_1_UTF8_HEX}-dir", + "/test-#{CHAR_1_UTF8_HEX}-dir", + "/test-#{CHAR_1_UTF8_HEX}-dir/" ].each do |path| entry = latin1_repo.entry(path, 2) - assert_equal "test-#{@char_1_utf8}-dir", entry.path + assert_equal "test-#{CHAR_1_UTF8_HEX}-dir", entry.path assert_equal "dir", entry.kind end - ["test-#{@char_1_utf8}-dir/test-#{@char_1_utf8}-1.txt", - "/test-#{@char_1_utf8}-dir/test-#{@char_1_utf8}-1.txt" + ["test-#{CHAR_1_UTF8_HEX}-dir/test-#{CHAR_1_UTF8_HEX}-1.txt", + "/test-#{CHAR_1_UTF8_HEX}-dir/test-#{CHAR_1_UTF8_HEX}-1.txt" ].each do |path| entry = latin1_repo.entry(path, 2) - assert_equal "test-#{@char_1_utf8}-dir/test-#{@char_1_utf8}-1.txt", + assert_equal "test-#{CHAR_1_UTF8_HEX}-dir/test-#{CHAR_1_UTF8_HEX}-1.txt", entry.path assert_equal "file", entry.kind end @@ -256,35 +248,33 @@ class RepositoryBazaarTest < ActiveSupport::TestCase cs2 = latin1_repo.changesets.find_by_revision('2') assert_not_nil cs2 - assert_equal "test-#{@char_1_utf8}", cs2.comments + assert_equal "test-#{CHAR_1_UTF8_HEX}", cs2.comments c2 = cs2.filechanges.sort_by(&:path) assert_equal 4, c2.size assert_equal 'A', c2[0].action - assert_equal "/test-#{@char_1_utf8}-dir/", c2[0].path + assert_equal "/test-#{CHAR_1_UTF8_HEX}-dir/", c2[0].path assert_equal 'A', c2[1].action - assert_equal "/test-#{@char_1_utf8}-dir/test-#{@char_1_utf8}-1.txt", c2[1].path + assert_equal "/test-#{CHAR_1_UTF8_HEX}-dir/test-#{CHAR_1_UTF8_HEX}-1.txt", c2[1].path assert_equal 'A', c2[2].action - assert_equal "/test-#{@char_1_utf8}-dir/test-#{@char_1_utf8}-2.txt", c2[2].path + assert_equal "/test-#{CHAR_1_UTF8_HEX}-dir/test-#{CHAR_1_UTF8_HEX}-2.txt", c2[2].path assert_equal 'A', c2[3].action - assert_equal "/test-#{@char_1_utf8}-dir/test-#{@char_1_utf8}.txt", c2[3].path + assert_equal "/test-#{CHAR_1_UTF8_HEX}-dir/test-#{CHAR_1_UTF8_HEX}.txt", c2[3].path cs3 = latin1_repo.changesets.find_by_revision('3') assert_not_nil cs3 - assert_equal "modify, move and delete #{@char_1_utf8} files", cs3.comments + assert_equal "modify, move and delete #{CHAR_1_UTF8_HEX} files", cs3.comments c3 = cs3.filechanges.sort_by(&:path) assert_equal 3, c3.size assert_equal 'M', c3[0].action - assert_equal "/test-#{@char_1_utf8}-1.txt", c3[0].path + assert_equal "/test-#{CHAR_1_UTF8_HEX}-1.txt", c3[0].path assert_equal 'D', c3[1].action - assert_equal "/test-#{@char_1_utf8}-dir/test-#{@char_1_utf8}-2.txt", c3[1].path + assert_equal "/test-#{CHAR_1_UTF8_HEX}-dir/test-#{CHAR_1_UTF8_HEX}-2.txt", c3[1].path assert_equal 'M', c3[2].action - assert_equal "/test-#{@char_1_utf8}-dir/test-#{@char_1_utf8}.txt", c3[2].path + assert_equal "/test-#{CHAR_1_UTF8_HEX}-dir/test-#{CHAR_1_UTF8_HEX}.txt", c3[2].path end else - msg = "Bazaar non ASCII output test cannot run this environment." + "\n" - if msg.respond_to?(:force_encoding) - msg += "Encoding.locale_charmap: " + Encoding.locale_charmap + "\n" - end + msg = "Bazaar non ASCII output test cannot run this environment.\n" + msg += "Encoding.locale_charmap: " + Encoding.locale_charmap + "\n" puts msg end diff --git a/test/unit/repository_cvs_test.rb b/test/unit/repository_cvs_test.rb index 223b8ec45..8b5ac6271 100644 --- a/test/unit/repository_cvs_test.rb +++ b/test/unit/repository_cvs_test.rb @@ -22,7 +22,7 @@ class RepositoryCvsTest < ActiveSupport::TestCase include Redmine::I18n - REPOSITORY_PATH = Rails.root.join('tmp/test/cvs_repository').to_s + REPOSITORY_PATH = repository_path('cvs') REPOSITORY_PATH.gsub!(/\//, "\\") if Redmine::Platform.mswin? # CVS module MODULE_NAME = 'test' @@ -52,8 +52,7 @@ class RepositoryCvsTest < ActiveSupport::TestCase def test_blank_module_error_message_fr set_language_if_valid 'fr' - str = "Module doit \xc3\xaatre renseign\xc3\xa9(e)" - str.force_encoding('UTF-8') if str.respond_to?(:force_encoding) + str = "Module doit \xc3\xaatre renseign\xc3\xa9(e)".force_encoding('UTF-8') repo = Repository::Cvs.new( :project => @project, :identifier => 'test', @@ -81,8 +80,7 @@ class RepositoryCvsTest < ActiveSupport::TestCase def test_blank_cvsroot_error_message_fr set_language_if_valid 'fr' - str = "CVSROOT doit \xc3\xaatre renseign\xc3\xa9(e)" - str.force_encoding('UTF-8') if str.respond_to?(:force_encoding) + str = "CVSROOT doit \xc3\xaatre renseign\xc3\xa9(e)".force_encoding('UTF-8') repo = Repository::Cvs.new( :project => @project, :identifier => 'test', diff --git a/test/unit/repository_darcs_test.rb b/test/unit/repository_darcs_test.rb index 255fcaf1c..9e98b0f2c 100644 --- a/test/unit/repository_darcs_test.rb +++ b/test/unit/repository_darcs_test.rb @@ -49,8 +49,7 @@ class RepositoryDarcsTest < ActiveSupport::TestCase def test_blank_path_to_repository_error_message_fr set_language_if_valid 'fr' - str = "Chemin du d\xc3\xa9p\xc3\xb4t doit \xc3\xaatre renseign\xc3\xa9(e)" - str.force_encoding('UTF-8') if str.respond_to?(:force_encoding) + str = "Chemin du d\xc3\xa9p\xc3\xb4t doit \xc3\xaatre renseign\xc3\xa9(e)".force_encoding('UTF-8') repo = Repository::Darcs.new( :project => @project, :url => "", diff --git a/test/unit/repository_filesystem_test.rb b/test/unit/repository_filesystem_test.rb index 1a4dfc737..dd6546518 100644 --- a/test/unit/repository_filesystem_test.rb +++ b/test/unit/repository_filesystem_test.rb @@ -47,8 +47,7 @@ class RepositoryFilesystemTest < ActiveSupport::TestCase def test_blank_root_directory_error_message_fr set_language_if_valid 'fr' - str = "R\xc3\xa9pertoire racine doit \xc3\xaatre renseign\xc3\xa9(e)" - str.force_encoding('UTF-8') if str.respond_to?(:force_encoding) + str = "R\xc3\xa9pertoire racine doit \xc3\xaatre renseign\xc3\xa9(e)".force_encoding('UTF-8') repo = Repository::Filesystem.new( :project => @project, :url => "", diff --git a/test/unit/repository_git_test.rb b/test/unit/repository_git_test.rb index c7836fe06..94e5747cc 100644 --- a/test/unit/repository_git_test.rb +++ b/test/unit/repository_git_test.rb @@ -28,8 +28,8 @@ class RepositoryGitTest < ActiveSupport::TestCase NUM_REV = 28 NUM_HEAD = 6 - FELIX_HEX = "Felix Sch\xC3\xA4fer" - CHAR_1_HEX = "\xc3\x9c" + FELIX_HEX = "Felix Sch\xC3\xA4fer".force_encoding('UTF-8') + CHAR_1_HEX = "\xc3\x9c".force_encoding('UTF-8') ## Git, Mercurial and CVS path encodings are binary. ## Subversion supports URL encoding for path. @@ -47,10 +47,6 @@ class RepositoryGitTest < ActiveSupport::TestCase :path_encoding => 'ISO-8859-1' ) assert @repository - @char_1 = CHAR_1_HEX.dup - if @char_1.respond_to?(:force_encoding) - @char_1.force_encoding('UTF-8') - end end def test_blank_path_to_repository_error_message @@ -66,8 +62,7 @@ class RepositoryGitTest < ActiveSupport::TestCase def test_blank_path_to_repository_error_message_fr set_language_if_valid 'fr' - str = "Chemin du d\xc3\xa9p\xc3\xb4t doit \xc3\xaatre renseign\xc3\xa9(e)" - str.force_encoding('UTF-8') if str.respond_to?(:force_encoding) + str = "Chemin du d\xc3\xa9p\xc3\xb4t doit \xc3\xaatre renseign\xc3\xa9(e)".force_encoding('UTF-8') repo = Repository::Git.new( :project => @project, :url => "", @@ -450,14 +445,14 @@ class RepositoryGitTest < ActiveSupport::TestCase else # latin-1 encoding path changesets = @repository.latest_changesets( - "latin-1-dir/test-#{@char_1}-2.txt", '64f1f3e89') + "latin-1-dir/test-#{CHAR_1_HEX}-2.txt", '64f1f3e89') assert_equal [ '64f1f3e89ad1cb57976ff0ad99a107012ba3481d', '4fc55c43bf3d3dc2efb66145365ddc17639ce81e', ], changesets.collect(&:revision) changesets = @repository.latest_changesets( - "latin-1-dir/test-#{@char_1}-2.txt", '64f1f3e89', 1) + "latin-1-dir/test-#{CHAR_1_HEX}-2.txt", '64f1f3e89', 1) assert_equal [ '64f1f3e89ad1cb57976ff0ad99a107012ba3481d', ], changesets.collect(&:revision) @@ -475,7 +470,7 @@ class RepositoryGitTest < ActiveSupport::TestCase @project.reload assert_equal NUM_REV, @repository.changesets.count changesets = @repository.latest_changesets( - "latin-1-dir/test-#{@char_1}-subdir", '1ca7f5ed') + "latin-1-dir/test-#{CHAR_1_HEX}-subdir", '1ca7f5ed') assert_equal [ '1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127', ], changesets.collect(&:revision) @@ -538,13 +533,9 @@ class RepositoryGitTest < ActiveSupport::TestCase @repository.fetch_changesets @project.reload assert_equal NUM_REV, @repository.changesets.count - str_felix_hex = FELIX_HEX.dup - if str_felix_hex.respond_to?(:force_encoding) - str_felix_hex.force_encoding('UTF-8') - end c = @repository.changesets.find_by_revision( 'ed5bb786bbda2dee66a2d50faf51429dbc043a7b') - assert_equal "#{str_felix_hex} <felix@fachschaften.org>", c.committer + assert_equal "#{FELIX_HEX} <felix@fachschaften.org>", c.committer end def test_previous diff --git a/test/unit/repository_mercurial_test.rb b/test/unit/repository_mercurial_test.rb index 9762e47a9..0518055a2 100644 --- a/test/unit/repository_mercurial_test.rb +++ b/test/unit/repository_mercurial_test.rb @@ -24,7 +24,9 @@ class RepositoryMercurialTest < ActiveSupport::TestCase REPOSITORY_PATH = Rails.root.join('tmp/test/mercurial_repository').to_s NUM_REV = 34 - CHAR_1_HEX = "\xc3\x9c" + + CHAR_1_HEX = "\xc3\x9c".force_encoding('UTF-8') + BRANCH_CHAR_1 = "branch-#{CHAR_1_HEX}-01".force_encoding('UTF-8') def setup @project = Project.find(3) @@ -34,16 +36,6 @@ class RepositoryMercurialTest < ActiveSupport::TestCase :path_encoding => 'ISO-8859-1' ) assert @repository - @char_1 = CHAR_1_HEX.dup - @tag_char_1 = "tag-#{CHAR_1_HEX}-00" - @branch_char_0 = "branch-#{CHAR_1_HEX}-00" - @branch_char_1 = "branch-#{CHAR_1_HEX}-01" - if @char_1.respond_to?(:force_encoding) - @char_1.force_encoding('UTF-8') - @tag_char_1.force_encoding('UTF-8') - @branch_char_0.force_encoding('UTF-8') - @branch_char_1.force_encoding('UTF-8') - end end def test_blank_path_to_repository_error_message @@ -59,8 +51,7 @@ class RepositoryMercurialTest < ActiveSupport::TestCase def test_blank_path_to_repository_error_message_fr set_language_if_valid 'fr' - str = "Chemin du d\xc3\xa9p\xc3\xb4t doit \xc3\xaatre renseign\xc3\xa9(e)" - str.force_encoding('UTF-8') if str.respond_to?(:force_encoding) + str = "Chemin du d\xc3\xa9p\xc3\xb4t doit \xc3\xaatre renseign\xc3\xa9(e)".force_encoding('UTF-8') repo = Repository::Mercurial.new( :project => @project, :url => "", @@ -362,11 +353,11 @@ class RepositoryMercurialTest < ActiveSupport::TestCase assert_equal NUM_REV, @repository.changesets.count if @repository.scm.class.client_version_above?([1, 6]) - changesets = @repository.latest_changesets('', @branch_char_1) + changesets = @repository.latest_changesets('', BRANCH_CHAR_1) assert_equal %w|27 26|, changesets.collect(&:revision) end - changesets = @repository.latest_changesets("latin-1-dir/test-#{@char_1}-subdir", @branch_char_1) + changesets = @repository.latest_changesets("latin-1-dir/test-#{CHAR_1_HEX}-subdir", BRANCH_CHAR_1) assert_equal %w|27|, changesets.collect(&:revision) end @@ -429,8 +420,8 @@ class RepositoryMercurialTest < ActiveSupport::TestCase scmid3 = scmid_for_assert(hex3, is_short_scmid) assert_equal 1, c3.size assert_equal 'A', c3[0].action - assert_equal "/latin-1-dir/test-#{@char_1}-1.txt", c3[0].path - assert_equal "/latin-1-dir/test-#{@char_1}.txt", c3[0].from_path + assert_equal "/latin-1-dir/test-#{CHAR_1_HEX}-1.txt", c3[0].path + assert_equal "/latin-1-dir/test-#{CHAR_1_HEX}.txt", c3[0].from_path assert_equal scmid3, c3[0].from_revision end private :assert_copied_files diff --git a/test/unit/repository_subversion_test.rb b/test/unit/repository_subversion_test.rb index d9b9a15f4..2fe50da14 100644 --- a/test/unit/repository_subversion_test.rb +++ b/test/unit/repository_subversion_test.rb @@ -202,13 +202,7 @@ class RepositorySubversionTest < ActiveSupport::TestCase def test_log_encoding_ignore_setting with_settings :commit_logs_encoding => 'windows-1252' do - s1 = "\xC2\x80" - s2 = "\xc3\x82\xc2\x80" - if s1.respond_to?(:force_encoding) - s1.force_encoding('ISO-8859-1') - s2.force_encoding('UTF-8') - assert_equal s1.encode('UTF-8'), s2 - end + s2 = "\xc3\x82\xc2\x80".force_encoding('UTF-8') c = Changeset.new(:repository => @repository, :comments => s2, :revision => '123', diff --git a/test/unit/repository_test.rb b/test/unit/repository_test.rb index 2de4972dc..9537e50a6 100644 --- a/test/unit/repository_test.rb +++ b/test/unit/repository_test.rb @@ -54,8 +54,7 @@ class RepositoryTest < ActiveSupport::TestCase def test_blank_log_encoding_error_message_fr set_language_if_valid 'fr' - str = "Encodage des messages de commit doit \xc3\xaatre renseign\xc3\xa9(e)" - str.force_encoding('UTF-8') if str.respond_to?(:force_encoding) + str = "Encodage des messages de commit doit \xc3\xaatre renseign\xc3\xa9(e)".force_encoding('UTF-8') repo = Repository::Bazaar.new( :project => Project.find(3), :url => "/test" @@ -175,7 +174,7 @@ class RepositoryTest < ActiveSupport::TestCase def test_destroy_should_delete_parents_associations changeset = Changeset.find(102) - changeset.parents = Changeset.where(:id => [100, 101]).all + changeset.parents = Changeset.where(:id => [100, 101]).to_a assert_difference 'Changeset.connection.select_all("select * from changeset_parents").count', -2 do Repository.find(10).destroy end @@ -183,7 +182,7 @@ class RepositoryTest < ActiveSupport::TestCase def test_destroy_should_delete_issues_associations changeset = Changeset.find(102) - changeset.issues = Issue.where(:id => [1, 2]).all + changeset.issues = Issue.where(:id => [1, 2]).to_a assert_difference 'Changeset.connection.select_all("select * from changesets_issues").count', -2 do Repository.find(10).destroy end diff --git a/test/unit/role_test.rb b/test/unit/role_test.rb index 710120dab..e1ba993ee 100644 --- a/test/unit/role_test.rb +++ b/test/unit/role_test.rb @@ -21,16 +21,16 @@ class RoleTest < ActiveSupport::TestCase fixtures :roles, :workflows, :trackers def test_sorted_scope - assert_equal Role.all.sort, Role.sorted.all + assert_equal Role.all.sort, Role.sorted.to_a end def test_givable_scope - assert_equal Role.all.reject(&:builtin?).sort, Role.givable.all + assert_equal Role.all.reject(&:builtin?).sort, Role.givable.to_a end def test_builtin_scope - assert_equal Role.all.select(&:builtin?).sort, Role.builtin(true).all.sort - assert_equal Role.all.reject(&:builtin?).sort, Role.builtin(false).all.sort + assert_equal Role.all.select(&:builtin?).sort, Role.builtin(true).to_a.sort + assert_equal Role.all.reject(&:builtin?).sort, Role.builtin(false).to_a.sort end def test_copy_from diff --git a/test/unit/tracker_test.rb b/test/unit/tracker_test.rb index 64f1078d1..70d892b77 100644 --- a/test/unit/tracker_test.rb +++ b/test/unit/tracker_test.rb @@ -21,7 +21,7 @@ class TrackerTest < ActiveSupport::TestCase fixtures :trackers, :workflows, :issue_statuses, :roles, :issues def test_sorted_scope - assert_equal Tracker.all.sort, Tracker.sorted.all + assert_equal Tracker.all.sort, Tracker.sorted.to_a end def test_named_scope diff --git a/test/unit/user_test.rb b/test/unit/user_test.rb index 187ec7c8b..df0e79f18 100644 --- a/test/unit/user_test.rb +++ b/test/unit/user_test.rb @@ -27,6 +27,8 @@ class UserTest < ActiveSupport::TestCase :groups_users, :enabled_modules + include Redmine::I18n + def setup @admin = User.find(1) @jsmith = User.find(2) @@ -34,8 +36,9 @@ class UserTest < ActiveSupport::TestCase end def test_sorted_scope_should_sort_user_by_display_name - assert_equal User.all.map(&:name).map(&:downcase).sort, - User.sorted.map(&:name).map(&:downcase) + # Use .active to ignore anonymous with localized display name + assert_equal User.active.map(&:name).map(&:downcase).sort, + User.active.sorted.map(&:name).map(&:downcase) end def test_generate @@ -853,29 +856,61 @@ class UserTest < ActiveSupport::TestCase end def test_roles_for_project_with_non_member_with_public_project_should_return_non_member + set_language_if_valid 'en' roles = User.find(8).roles_for_project(Project.find(1)) assert_equal ["Non member"], roles.map(&:name) end - def test_roles_for_project_with_non_member_with_public_project_should_return_no_roles + def test_roles_for_project_with_non_member_with_public_project_and_override_should_return_override_roles + project = Project.find(1) + Member.create!(:project => project, :principal => Group.non_member, :role_ids => [1, 2]) + roles = User.find(8).roles_for_project(project) + assert_equal ["Developer", "Manager"], roles.map(&:name).sort + end + + def test_roles_for_project_with_non_member_with_private_project_should_return_no_roles Project.find(1).update_attribute :is_public, false roles = User.find(8).roles_for_project(Project.find(1)) assert_equal [], roles.map(&:name) end + def test_roles_for_project_with_non_member_with_private_project_and_override_should_return_no_roles + project = Project.find(1) + project.update_attribute :is_public, false + Member.create!(:project => project, :principal => Group.non_member, :role_ids => [1, 2]) + roles = User.find(8).roles_for_project(project) + assert_equal [], roles.map(&:name).sort + end + def test_roles_for_project_with_anonymous_with_public_project_should_return_anonymous + set_language_if_valid 'en' roles = User.anonymous.roles_for_project(Project.find(1)) assert_equal ["Anonymous"], roles.map(&:name) end - def test_roles_for_project_with_anonymous_with_public_project_should_return_no_roles + def test_roles_for_project_with_anonymous_with_public_project_and_override_should_return_override_roles + project = Project.find(1) + Member.create!(:project => project, :principal => Group.anonymous, :role_ids => [1, 2]) + roles = User.anonymous.roles_for_project(project) + assert_equal ["Developer", "Manager"], roles.map(&:name).sort + end + + def test_roles_for_project_with_anonymous_with_private_project_should_return_no_roles Project.find(1).update_attribute :is_public, false roles = User.anonymous.roles_for_project(Project.find(1)) assert_equal [], roles.map(&:name) end + def test_roles_for_project_with_anonymous_with_private_project_and_override_should_return_no_roles + project = Project.find(1) + project.update_attribute :is_public, false + Member.create!(:project => project, :principal => Group.anonymous, :role_ids => [1, 2]) + roles = User.anonymous.roles_for_project(project) + assert_equal [], roles.map(&:name).sort + end + def test_projects_by_role_for_user_with_role user = User.find(2) assert_kind_of Hash, user.projects_by_role @@ -1059,10 +1094,10 @@ class UserTest < ActiveSupport::TestCase end should "return true only if user has permission on all these projects" do - assert_equal true, @admin.allowed_to?(:view_project, Project.all) - assert_equal false, @dlopper.allowed_to?(:view_project, Project.all) #cannot see Project(2) - assert_equal true, @jsmith.allowed_to?(:edit_issues, @jsmith.projects) #Manager or Developer everywhere - assert_equal false, @jsmith.allowed_to?(:delete_issue_watchers, @jsmith.projects) #Dev cannot delete_issue_watchers + assert_equal true, @admin.allowed_to?(:view_project, Project.all.to_a) + assert_equal false, @dlopper.allowed_to?(:view_project, Project.all.to_a) #cannot see Project(2) + assert_equal true, @jsmith.allowed_to?(:edit_issues, @jsmith.projects.to_a) #Manager or Developer everywhere + assert_equal false, @jsmith.allowed_to?(:delete_issue_watchers, @jsmith.projects.to_a) #Dev cannot delete_issue_watchers end should "behave correctly with arrays of 1 project" do diff --git a/test/unit/version_test.rb b/test/unit/version_test.rb index 55a315af0..a1dddd905 100644 --- a/test/unit/version_test.rb +++ b/test/unit/version_test.rb @@ -124,7 +124,7 @@ class VersionTest < ActiveSupport::TestCase v5 = Version.create!(:project_id => 1, :name => 'v5', :effective_date => '2012-07-02') assert_equal [v5, v3, v1, v2, v4], [v1, v2, v3, v4, v5].sort - assert_equal [v5, v3, v1, v2, v4], Version.sorted.all + assert_equal [v5, v3, v1, v2, v4], Version.sorted.to_a end def test_completed_should_be_false_when_due_today diff --git a/test/unit/wiki_test.rb b/test/unit/wiki_test.rb index e363b4134..a852b2393 100644 --- a/test/unit/wiki_test.rb +++ b/test/unit/wiki_test.rb @@ -78,8 +78,7 @@ class WikiTest < ActiveSupport::TestCase end def test_titleize - ja_test = "\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88" - ja_test.force_encoding('UTF-8') if ja_test.respond_to?(:force_encoding) + ja_test = "\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88".force_encoding('UTF-8') assert_equal 'Page_title_with_CAPITALES', Wiki.titleize('page title with CAPITALES') assert_equal ja_test, Wiki.titleize(ja_test) end |