--- /dev/null
+#! /bin/sh
+
+JRUBY_OPTS=-J-Xmx1024m bundle exec rake test:${TEST_SUITE}
# You can also run tests on your environment.
language: ruby
rvm:
- - 1.8.7
- - 1.9.2
- 1.9.3
- 2.0
- 2.1
- "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
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
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
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]
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
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
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
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
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
@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?
}
reorder('created_on DESC').
includes(:author, :board).
limit(Setting.feeds_limit.to_i).
- all
+ to_a
render_feed(@messages, :title => "#{@project}: #{@board}")
}
end
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 }
end
def show
- @attachments = @document.attachments.all
+ @attachments = @document.attachments.to_a
end
def new
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
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
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
redirect_to enumerations_path
return
end
- @enumerations = @enumeration.class.system.all - [@enumeration]
+ @enumerations = @enumeration.class.system.to_a - [@enumeration]
end
private
'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
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
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') }
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
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
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? }
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
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
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)
@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
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)
order("#{Member.table_name}.id").
limit(@limit).
offset(@offset).
- all
+ to_a
respond_to do |format|
format.html { head 406 }
format.api
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?
@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?
@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
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
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)
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]
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)
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?)
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
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
private
def find_issue_statuses
- @statuses = IssueStatus.sorted.all
+ @statuses = IssueStatus.sorted.to_a
end
end
@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'
@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)
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? }
render :action => "index", :layout => false if request.xhr?
}
format.api {
- @roles = Role.givable.all
+ @roles = Role.givable.to_a
}
end
end
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
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
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
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|
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
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],
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|
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?
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
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
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
redirect_to fields_trackers_path
return
end
- @trackers = Tracker.sorted.all
+ @trackers = Tracker.sorted.to_a
@custom_fields = IssueCustomField.all.sort
end
end
@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 {
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)
@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]
# 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
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]
@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
@issues = @version.fixed_issues.visible.
includes(:status, :tracker, :priority).
reorder("#{Tracker.table_name}.position, #{Issue.table_name}.id").
- all
+ to_a
}
format.api
end
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
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
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?
reorder('version DESC').
limit(@version_pages.per_page + 1).
offset(@version_pages.offset).
- all
+ to_a
render :layout => false if request.xhr?
end
@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
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
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)
reorder("#{WikiPage.table_name}.title").
includes(:wiki => :project).
includes(:parent).
- all
+ to_a
end
end
@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)
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
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
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
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
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?
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'
end
def format_version_name(version)
- if !version.shared? || version.project == @project
+ if version.project == @project
h(version)
else
h("#{version.project} - #{version}")
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')
source
end
end
- super sources, options
+ super *sources, options
end
# Overrides Rails' image_tag with themes and plugins support.
end
end
end
- super sources, options
+ super *sources, options
end
# TODO: remove this in 2.5.0
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
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')
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
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
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
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')
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
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
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
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
# 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},
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
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
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
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
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}}
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")
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
validates_presence_of :name
validates_uniqueness_of :name
validates_length_of :name, :maximum => 60
+ attr_protected :id
def authenticate(login, password)
end
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"})'
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'
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)
: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
belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
validates_presence_of :commented, :author, :comments
+ attr_protected :id
after_create :send_notification
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|
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
# 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
class CustomValue < ActiveRecord::Base
belongs_to :custom_field
belongs_to :customized, :polymorphic => true
+ attr_protected :id
def initialize(attributes=nil, *args)
super
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'
validates_presence_of :name
validates_uniqueness_of :name, :scope => :project_id
+ attr_protected :id
after_create :module_enabled
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
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
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
super(attr_name, *args)
end
- def self.builtin_id(arg)
- (arg.anonymous? ? GroupAnonymous : GroupNonMember).instance_id
- end
-
def self.anonymous
GroupAnonymous.load_instance
end
def builtin_type
"anonymous"
end
-
- def self.instance_id
- @@instance_id ||= load_instance.id
- end
end
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
def builtin_type
"non_member"
end
-
- def self.instance_id
- @@instance_id ||= load_instance.id
- end
end
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
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)
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}
# 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
# 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
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')
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
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
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} +
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
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
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
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
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'").
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'
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}))"
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)
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!
scope = scope.preload(:author)
end
- issues = scope.all
+ issues = scope.to_a
if has_column?(:spent_hours)
Issue.load_visible_spent_hours(issues)
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
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
where(project_statement).
where(options[:conditions]).
includes(:project).
- all
+ references(:project).
+ to_a
rescue ::ActiveRecord::StatementInvalid => e
raise StatementInvalid.new(e.message)
end
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 ||= []
" 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' : ''
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
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]
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)}
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
[]
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,
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)
}
class JournalDetail < ActiveRecord::Base
belongs_to :journal
before_save :normalize_values
+ attr_protected :id
def custom_field
if property == 'cf'
@@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
end
parts.reject! do |part|
- part.header[:content_disposition].try(:disposition_type) == 'attachment'
+ part.attachment?
end
@plain_text_body = parts.map do |p|
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
validates_presence_of :role
validate :validate_role_member
+ attr_protected :id
def validate_role_member
errors.add :role_id, :invalid if role && !role.member?
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}"},
: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
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'
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
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'
# 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
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
# 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)
# 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'
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
# 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.
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
# 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
@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
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
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'" +
# 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
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
save
end
end
+ true
end
# Returns a new unsaved Project instance with attributes copied from +project+
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
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
end
def all_projects
- @all_projects ||= Project.visible.all
+ @all_projects ||= Project.visible.to_a
end
def all_projects_values
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
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"
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)
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
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)
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
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
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',
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).
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 =~ /^([^<]+)(<(.*)>)?$/
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
# 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
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
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
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?
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
# 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,
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 = {}
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
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
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
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,
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)
class Token < ActiveRecord::Base
belongs_to :user
validates_uniqueness_of :value
+ attr_protected :id
before_create :delete_previous_tokens, :generate_new_token
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
# 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
: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}") }
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
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, '')
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|
# 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?
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
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',
end
end
- # Returns true if the version is shared, otherwise false
- def shared?
- sharing != 'none'
- end
-
private
def load_issue_counts
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)
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'
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
: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
# uncompressed data
data
end
- str.force_encoding("UTF-8") if str.respond_to?(:force_encoding)
+ str.force_encoding("UTF-8")
str
end
end
: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"
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
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
validates_presence_of :title, :redirects_to
validates_length_of :title, :redirects_to, :maximum => 255
+ attr_protected :id
end
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)
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|
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|
<% 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>
<% roles = Role.find_all_givable %>
-<% projects = Project.active.all %>
+<% projects = Project.active.to_a %>
<div class="splitcontentleft">
<% if @group.memberships.any? %>
<%= 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? %>
<% 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>
<% roles = Role.find_all_givable %>
-<% projects = Project.active.all %>
+<% projects = Project.active.to_a %>
<div class="splitcontentleft">
<% if @user.memberships.any? %>
<%= 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 %>
<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>
--- /dev/null
+#!/usr/bin/env ruby
+
+ENV["RAILS_ENV"] ||= "production"
+require File.expand_path(File.dirname(__FILE__) + "/../config/environment")
+puts
+puts Redmine::Info.environment
--- /dev/null
+#!/usr/bin/env ruby.exe
+ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
+load Gem.bin_path('bundler', 'bundle')
--- /dev/null
+#!/usr/bin/env ruby.exe
+APP_PATH = File.expand_path('../../config/application', __FILE__)
+require_relative '../config/boot'
+require 'rails/commands'
--- /dev/null
+#!/usr/bin/env ruby.exe
+require_relative '../config/boot'
+require 'rake'
+Rake.application.run
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
# 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"
-require 'rubygems'
-
# Set up gems listed in the Gemfile.
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
-# 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).
-# 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
exit 1
end
-# Initialize the rails application
-RedmineApp::Application.initialize!
+# Initialize the Rails application
+Rails.application.initialize!
-# 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
-# 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
-# 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
# 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'
+# Same as test.rb
instance_eval File.read(File.join(File.dirname(__FILE__), 'test.rb'))
+# Same as test.rb
instance_eval File.read(File.join(File.dirname(__FILE__), 'test.rb'))
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
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'
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
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: タイトル
field_activity: 活動
field_spent_on: 日付
field_identifier: 識別子
- field_is_filter: フィルタとして使用
+ field_is_filter: フィルタとして使う
field_issue_to: 関連するチケット
field_delay: 遅延
field_assignable: このロールにチケットを割り当て可能
field_column_names: 項目
field_time_entries: 時間を記録
field_time_zone: タイムゾーン
- field_searchable: 検索対象
+ field_searchable: 検索条件に設定可能とする
field_default_value: デフォルト値
field_comments_sorting: コメントの表示順
field_parent_title: 親ページ
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: 整数
label_only: 僅於
label_drop_down_list: 下拉式清單
label_checkboxes: 核取方塊
- label_radio_buttons: 選項按鈕
label_link_values_to: 連結欄位值至此網址
label_custom_field_select_type: 請選擇連結此自訂欄位的物件類型
label_check_for_updates: 檢查更新
description_date_from: 輸入起始日期
description_date_to: 輸入結束日期
text_repository_identifier_info: '僅允許使用小寫英文字母 (a-z), 阿拉伯數字, 虛線與底線。<br />一旦儲存之後, 代碼便無法再次被更改。'
+ label_radio_buttons: radio buttons
+++ /dev/null
-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
# 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]
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]
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'
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]
post 'rename'
get 'history'
get 'diff'
- match 'preview', :via => [:post, :put]
+ match 'preview', :via => [:post, :put, :patch]
post 'protect'
post 'add_attachment'
end
class Setup < ActiveRecord::Migration
- class User < ActiveRecord::Base; end
+ class User < ActiveRecord::Base
+ attr_protected :id
+ end
+
# model removed
class Permission < ActiveRecord::Base; end
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
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
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
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
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
# 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
* 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
== 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
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
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
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)
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
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
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
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
# * :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
# 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]
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)
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
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
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").
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)}
+++ /dev/null
-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
+++ /dev/null
-awesome_nested_set.sqlite3.db
-spec/debug.log
-rdoc
-coverage
-pkg
-*.gem
-Gemfile.lock
-gemfiles/Gemfile*.lock
\ No newline at end of file
+++ /dev/null
-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
+++ /dev/null
-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
+++ /dev/null
-# 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.
+++ /dev/null
-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'
+++ /dev/null
-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.
+++ /dev/null
-# 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
+++ /dev/null
-# -*- 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
+++ /dev/null
-# -*- 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
+++ /dev/null
-MYSQL2_VERSION = '~> 0.2.18'
-RAILS_VERSION = '~> 3.0.17'
-
-eval File.read(File.expand_path('../../Gemfile', __FILE__))
+++ /dev/null
-MYSQL2_VERSION = '>= 0.3'
-RAILS_VERSION = '~> 3.1.0'
-
-eval File.read(File.expand_path('../../Gemfile', __FILE__))
+++ /dev/null
-MYSQL2_VERSION = '>= 0.3'
-RAILS_VERSION = '~> 3.2.0'
-
-eval File.read(File.expand_path('../../Gemfile', __FILE__))
+++ /dev/null
-require File.dirname(__FILE__) + '/lib/awesome_nested_set'
+++ /dev/null
-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
+++ /dev/null
-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
+++ /dev/null
-# 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
+++ /dev/null
-# -*- 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
+++ /dev/null
-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
+++ /dev/null
-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
+++ /dev/null
-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
+++ /dev/null
-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
+++ /dev/null
-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
+++ /dev/null
-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
+++ /dev/null
-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
+++ /dev/null
-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
+++ /dev/null
-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
+++ /dev/null
-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
+++ /dev/null
-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
+++ /dev/null
-module AwesomeNestedSet
- VERSION = '2.1.7' unless defined?(::AwesomeNestedSet::VERSION)
-end
+++ /dev/null
-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
+++ /dev/null
-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
+++ /dev/null
-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
+++ /dev/null
-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
+++ /dev/null
-one:
- id: 1
- name: One
\ No newline at end of file
+++ /dev/null
-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
+++ /dev/null
-top:
- id: 1
- name: Top
\ No newline at end of file
+++ /dev/null
-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
+++ /dev/null
-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
+++ /dev/null
-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
+++ /dev/null
-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
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"
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
-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
# 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
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
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
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
where("child.id IN (?)", ids).
order("#{Project.table_name}.lft ASC").
uniq.
- all
+ to_a
else
@projects = []
end
# * 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)
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
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
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
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
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
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
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
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
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
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)
# 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
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
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
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']
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)
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
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
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|
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|
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|
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
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
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"
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']
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)
desc 'Mantis migration script'
require 'active_record'
-require 'iconv' if RUBY_VERSION < '1.9'
require 'pp'
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
# 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
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}"
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
#!/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."
#!/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."
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',
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
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/',
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
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
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
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'
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'
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
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
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
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,
: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
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,
: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
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
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'
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'})
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
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
: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',
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
: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)
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
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)
: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' },
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]
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.
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)
: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
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'
:content => '1',
:attributes => { :class => 'line-num' },
:sibling => { :tag => 'td',
- :content => /test-#{@char_1}.txt/ }
+ :content => /test-#{CHAR_1_HEX}.txt/ }
end
end
end
: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
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
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
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
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
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
)
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)
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'
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][]',
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'
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"
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)
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"
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
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)
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
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'}))
: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
@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
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'
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'
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
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
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,
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
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
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
require File.expand_path('../../test_helper', __FILE__)
-class ApplicationTest < ActionController::IntegrationTest
+class ApplicationTest < ActionDispatch::IntegrationTest
include Redmine::I18n
fixtures :projects, :trackers, :issue_statuses, :issues,
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,
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,
require File.expand_path('../../test_helper', __FILE__)
-class IssuesTest < ActionController::IntegrationTest
+class IssuesTest < ActionDispatch::IntegrationTest
fixtures :projects,
:users,
:roles,
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
: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!
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,
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
end
end
+ Redmine::Hook.clear_listeners
+
class ContentForInsideHook < Redmine::Hook::ViewListener
render_on :view_welcome_index_left, :inline => <<-VIEW
<% content_for :header_tags do %>
require File.expand_path('../../../../test_helper', __FILE__)
-class MenuManagerTest < ActionController::IntegrationTest
+class MenuManagerTest < ActionDispatch::IntegrationTest
include Redmine::I18n
fixtures :projects, :trackers, :issue_statuses, :issues,
require File.expand_path('../../../../test_helper', __FILE__)
-class ThemesTest < ActionController::IntegrationTest
+class ThemesTest < ActionDispatch::IntegrationTest
def setup
@theme = Redmine::Themes.themes.last
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
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
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(
require File.expand_path('../../../test_helper', __FILE__)
-class RoutingActivitiesTest < ActionController::IntegrationTest
+class RoutingActivitiesTest < ActionDispatch::IntegrationTest
def test_activities
assert_routing(
{ :method => 'get', :path => "/activity" },
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" },
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" },
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" },
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" },
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" },
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" },
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" },
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(
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" },
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" },
require File.expand_path('../../../test_helper', __FILE__)
-class RoutingEnumerationsTest < ActionController::IntegrationTest
+class RoutingEnumerationsTest < ActionDispatch::IntegrationTest
def test_enumerations
assert_routing(
{ :method => 'get', :path => "/enumerations" },
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" },
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" },
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" },
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" },
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" },
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" },
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" },
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" },
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" },
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" },
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" },
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(
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" },
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(
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" },
require File.expand_path('../../../test_helper', __FILE__)
-class RoutingProjectsTest < ActionController::IntegrationTest
+class RoutingProjectsTest < ActionDispatch::IntegrationTest
def test_projects
assert_routing(
{ :method => 'get', :path => "/projects" },
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" },
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" },
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]
require File.expand_path('../../../test_helper', __FILE__)
-class RoutingRolesTest < ActionController::IntegrationTest
+class RoutingRolesTest < ActionDispatch::IntegrationTest
def test_roles
assert_routing(
{ :method => 'get', :path => "/roles" },
require File.expand_path('../../../test_helper', __FILE__)
-class RoutingSearchTest < ActionController::IntegrationTest
+class RoutingSearchTest < ActionDispatch::IntegrationTest
def test_search
assert_routing(
{ :method => 'get', :path => "/search" },
require File.expand_path('../../../test_helper', __FILE__)
-class RoutingSettingsTest < ActionController::IntegrationTest
+class RoutingSettingsTest < ActionDispatch::IntegrationTest
def test_settings
assert_routing(
{ :method => 'get', :path => "/settings" },
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" },
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" },
require File.expand_path('../../../test_helper', __FILE__)
-class RoutingTrackersTest < ActionController::IntegrationTest
+class RoutingTrackersTest < ActionDispatch::IntegrationTest
def test_trackers
assert_routing(
{ :method => 'get', :path => "/trackers" },
require File.expand_path('../../../test_helper', __FILE__)
-class RoutingUsersTest < ActionController::IntegrationTest
+class RoutingUsersTest < ActionDispatch::IntegrationTest
def test_users
assert_routing(
{ :method => 'get', :path => "/users" },
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(
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" },
require File.expand_path('../../../test_helper', __FILE__)
-class RoutingWelcomeTest < ActionController::IntegrationTest
+class RoutingWelcomeTest < ActionDispatch::IntegrationTest
def test_welcome
assert_routing(
{ :method => 'get', :path => "/" },
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" },
: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
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(
require File.expand_path('../../../test_helper', __FILE__)
-class RoutingWorkflowsTest < ActionController::IntegrationTest
+class RoutingWorkflowsTest < ActionDispatch::IntegrationTest
def test_workflows
assert_routing(
{ :method => 'get', :path => "/workflows" },
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
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
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
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
# 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
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',
: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',
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',
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,
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',
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
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
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
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
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
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
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
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
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
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
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
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?
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
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
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
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
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
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
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
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
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?}
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
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?}
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
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
# 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?}
: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
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?}
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
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)}
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
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
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!
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
def setup
@journal = Journal.find 1
+ User.current = nil
end
def test_journalized_is_an_issue
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
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
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?}
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
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
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
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
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)
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
def setup
@hook_module = Redmine::Hook
+ @hook_module.clear_listeners
end
def teardown
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
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
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
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
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
# 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
# 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
-
# 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
-
# 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
# 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
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
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
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
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
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')
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')
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')
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')
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')
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
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(
)
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
)
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
)
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
)
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
'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
: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
: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
: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
: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
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
Setting.host_name = 'mydomain.foo'
Setting.protocol = 'http'
Setting.plain_text_mail = '0'
+ User.current = nil
end
def test_generated_links_in_emails
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
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
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?}
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!
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'))
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
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
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
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)
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
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
# 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)
: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
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 => "",
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
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
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'
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',
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',
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 => "",
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 => "",
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.
: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
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 => "",
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)
@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)
@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
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)
: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
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 => "",
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
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
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',
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"
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
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
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
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
:groups_users,
:enabled_modules
+ include Redmine::I18n
+
def setup
@admin = User.find(1)
@jsmith = User.find(2)
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
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
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
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
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