diff --git a/Gemfile b/Gemfile index 035f5e4f7f..ae9388a534 100644 --- a/Gemfile +++ b/Gemfile @@ -39,14 +39,18 @@ group :test do gem 'mocha' gem "launchy", "~> 2.1.0" gem "factory_girl_rails", "~> 4.0" - gem 'cucumber-rails' + gem 'cucumber-rails', :require => false gem 'database_cleaner' gem "rspec-rails", "~> 2.0", :group => :development gem 'capybara' + gem 'spork-rails' + gem 'spork-testunit' # needed for test-unit only gem 'ruby-debug', :platforms => [:mri_18, :mingw_18] # TODO: remove dependency to v 1.1.3 when pry-debugger is updated to > 0.2 gem 'debugger', '~> 1.1.3', :platforms => [:mri_19, :mingw_19] + # why in Gemfile? see: https://github.com/guard/guard-test + gem 'ruby-prof' end group :openid do @@ -57,6 +61,11 @@ group :development do gem 'rails-footnotes', '>= 3.7.5.rc4' gem 'bullet' gem 'letter_opener', '~> 1.0.0' + gem 'rails-dev-tweaks', '~> 0.6.1' + gem 'guard-rspec' + gem 'guard-cucumber' + gem 'guard-spork' + gem 'rb-fsevent', :group => :test, :require => false if RUBY_PLATFORM =~ /darwin/i end group :development, :test do @@ -67,6 +76,11 @@ group :development, :test do gem 'pry-doc' end +group :tools do + # why tools? see: https://github.com/guard/guard-test + gem 'guard-test' +end + group :rmagick do gem "rmagick", ">= 1.15.17" # Older distributions might not have a sufficiently new ImageMagick version diff --git a/Gemfile.lock b/Gemfile.lock index edbb7f2ff6..53c08b38f9 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -104,6 +104,25 @@ GEM ffi (1.1.5) gherkin (2.11.5) json (>= 1.4.6) + guard (1.5.0) + listen (>= 0.4.2) + lumberjack (>= 1.0.2) + pry (>= 0.9.10) + thor (>= 0.14.6) + guard-cucumber (1.2.0) + cucumber (>= 1.2.0) + guard (>= 1.1.0) + guard-rspec (2.1.0) + guard (>= 1.1) + rspec (~> 2.11) + guard-spork (1.2.1) + childprocess (>= 0.2.3) + guard (>= 1.1) + spork (>= 0.8.4) + sys-proctable + guard-test (0.5.0) + guard (>= 1.1.0) + test-unit (~> 2.2) hike (1.2.1) htmldiff (0.0.1) i18n (0.6.1) @@ -121,8 +140,10 @@ GEM addressable linecache (0.46) rbx-require-relative (> 0.0.4) + listen (0.5.3) loofah (1.2.1) nokogiri (>= 1.4.4) + lumberjack (1.0.2) mail (2.4.4) i18n (>= 0.4.0) mime-types (~> 1.16) @@ -175,6 +196,9 @@ GEM activesupport (= 3.2.8) bundler (~> 1.0) railties (= 3.2.8) + rails-dev-tweaks (0.6.1) + actionpack (~> 3.1) + railties (~> 3.1) rails-footnotes (3.7.8) rails (>= 3.0.0) rails_autolink (1.0.9) @@ -210,6 +234,7 @@ GEM ruby-debug-base (0.10.4) linecache (>= 0.3) ruby-openid (2.1.8) + ruby-prof (0.11.2) rubytree (0.8.3) json (>= 1.7.5) structured_warnings (>= 0.1.3) @@ -231,13 +256,21 @@ GEM shoulda-matchers (1.4.1) activesupport (>= 3.0.0) slop (3.3.3) - sprockets (2.1.3) + spork (1.0.0rc3) + spork-rails (3.2.0) + rails (>= 3.0.0, < 3.3.0) + spork (>= 1.0rc0) + spork-testunit (0.0.8) hike (~> 1.2) rack (~> 1.0) + spork (>= 0.6.0) tilt (~> 1.1, != 1.3.0) + sprockets (2.1.3) sqlite3 (1.3.6) sqlite3-ruby (1.2.5) structured_warnings (0.1.3) + sys-proctable (0.9.2) + test-unit (2.5.2) thor (0.16.0) tilt (1.3.3) tinymce-rails (3.5.7.1) @@ -275,6 +308,10 @@ DEPENDENCIES factory_girl_rails (~> 4.0) fastercsv (~> 1.5.0) globalize3! + guard-cucumber + guard-rspec + guard-spork + guard-test htmldiff jquery-rails jruby-openssl @@ -293,6 +330,7 @@ DEPENDENCIES pry-rescue pry-stack_explorer rails (= 3.2.8) + rails-dev-tweaks (~> 0.6.1) rails-footnotes (>= 3.7.5.rc4) rails_autolink rdoc (>= 2.4.2) @@ -300,9 +338,12 @@ DEPENDENCIES rspec-rails (~> 2.0) ruby-debug ruby-openid (~> 2.1.4) + ruby-prof rubytree (~> 0.8.3) sass-rails (~> 3.2.3) shoulda (~> 3.1.1) + spork-rails + spork-testunit sqlite3 sqlite3-ruby (< 1.3) tinymce-rails diff --git a/Guardfile b/Guardfile new file mode 100644 index 0000000000..8dea335f05 --- /dev/null +++ b/Guardfile @@ -0,0 +1,52 @@ +# :spork guard must come first +# guard :spork, :cucumber_env => { 'RAILS_ENV' => 'test' }, :rspec_env => { 'RAILS_ENV' => 'test' } do +# watch('config/application.rb') +# watch('config/environment.rb') +# watch('config/environments/test.rb') +# watch(%r{^config/initializers/.+\.rb$}) +# watch('Gemfile') +# watch('Gemfile.lock') +# watch('spec/spec_helper.rb') { :rspec } +# watch(%r{^spec/support/.+\.rb$}) { :rspec } +# watch('test/test_helper.rb') { :test } +# watch(%r{features/support/}) { :cucumber } +# end + +# guard :rspec, :cli => "--drb" do +# watch(%r{^spec/.+_spec\.rb$}) +# watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" } +# watch('spec/spec_helper.rb') { "spec" } +# +# # Rails example +# watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" } +# watch(%r{^app/(.*)(\.erb|\.haml)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" } +# watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] } +# watch(%r{^spec/support/(.+)\.rb$}) { "spec" } +# watch('config/routes.rb') { "spec/routing" } +# watch('app/controllers/application_controller.rb') { "spec/controllers" } +# +# # Capybara request specs +# watch(%r{^app/views/(.+)/.*\.(erb|haml)$}) { |m| "spec/requests/#{m[1]}_spec.rb" } +# +# # Turnip features and steps +# watch(%r{^spec/acceptance/(.+)\.feature$}) +# watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' } +# end +# +# guard :cucumber do # , :cli => "--drb" do +# watch(%r{^features/.+\.feature$}) +# watch(%r{^features/support/.+$}) { 'features' } +# watch(%r{^features/step_definitions/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'features' } +# end + +guard :test, :all_on_start => false, :all_after_pass => false do # , :drb => true do + watch(%r{^lib/(.+)\.rb$}) { |m| "test/#{m[1]}_test.rb" } + watch(%r{^test/.+_test\.rb$}) + watch('test/test_helper.rb') { "test" } + + # Rails example + watch(%r{^app/models/(.+)\.rb$}) { |m| "test/unit/#{m[1]}_test.rb" } + watch(%r{^app/controllers/(.+)\.rb$}) { |m| "test/functional/#{m[1]}_test.rb" } + watch(%r{^app/views/.+\.rb$}) { "test/integration" } + watch('app/controllers/application_controller.rb') { ["test/functional", "test/integration"] } +end diff --git a/app/helpers/attachments_helper.rb b/app/helpers/attachments_helper.rb index a3220f49f1..be0c3dabac 100644 --- a/app/helpers/attachments_helper.rb +++ b/app/helpers/attachments_helper.rb @@ -34,9 +34,8 @@ module AttachmentsHelper end begin - Iconv.conv('UTF-8//IGNORE', 'UTF-8', str + ' ')[0..-3] - rescue Iconv::InvalidEncoding - # "UTF-8//IGNORE" is not supported on some OS + (str + ' ').encode("UTF-8", :invalid => :replace, :undef => :replace, :replace => "?")[0..-3] + rescue Encoding::InvalidByteSequenceError, Encoding::UndefinedConversionError str end end diff --git a/app/helpers/issues_helper.rb b/app/helpers/issues_helper.rb index ad484f6a33..153d21f9a9 100644 --- a/app/helpers/issues_helper.rb +++ b/app/helpers/issues_helper.rb @@ -158,7 +158,6 @@ module IssuesHelper end def issues_to_csv(issues, project = nil) - ic = Iconv.new(l(:general_csv_encoding), 'UTF-8') decimal_separator = l(:general_csv_decimal_separator) export = FCSV.generate(:col_sep => l(:general_csv_separator)) do |csv| # csv header fields @@ -186,7 +185,7 @@ module IssuesHelper custom_fields.each {|f| headers << f.name} # Description in the last column headers << l(:field_description) - csv << headers.collect {|c| begin; ic.iconv(c.to_s); rescue; c.to_s; end } + csv << headers.collect {|c| begin; c.to_s.encode(l(:general_csv_encoding), 'UTF-8'); rescue; c.to_s; end } # csv lines issues.each do |issue| fields = [issue.id, @@ -209,7 +208,7 @@ module IssuesHelper ] custom_fields.each {|f| fields << show_value(issue.custom_value_for(f)) } fields << issue.description - csv << fields.collect {|c| begin; ic.iconv(c.to_s); rescue; c.to_s; end } + csv << fields.collect {|c| begin; c.to_s.encode(l(:general_csv_encoding), 'UTF-8'); rescue; c.to_s; end } end end export diff --git a/app/helpers/repositories_helper.rb b/app/helpers/repositories_helper.rb index c6b92f84a7..388304af2b 100644 --- a/app/helpers/repositories_helper.rb +++ b/app/helpers/repositories_helper.rb @@ -12,8 +12,6 @@ # See doc/COPYRIGHT.rdoc for more details. #++ -require 'iconv' - module RepositoriesHelper def format_revision(revision) if revision.respond_to? :format_identifier @@ -135,8 +133,8 @@ module RepositoriesHelper @encodings ||= Setting.repositories_encodings.split(',').collect(&:strip) @encodings.each do |encoding| begin - return Iconv.conv('UTF-8', encoding, str) - rescue Iconv::Failure + return str.to_s.encode('UTF-8', encoding) + rescue Encoding::InvalidByteSequenceError, Encoding::UndefinedConversionError # do nothing here and try the next encoding end end @@ -155,9 +153,8 @@ module RepositoriesHelper else # removes invalid UTF8 sequences begin - str = Iconv.conv('UTF-8//IGNORE', 'UTF-8', str + ' ')[0..-3] - rescue Iconv::InvalidEncoding - # "UTF-8//IGNORE" is not supported on some OS + (str + ' ').encode("UTF-8", :invalid => :replace, :undef => :replace, :replace => "?")[0..-3] + rescue Encoding::InvalidByteSequenceError, Encoding::UndefinedConversionError end end str diff --git a/app/helpers/timelog_helper.rb b/app/helpers/timelog_helper.rb index f1cc4f049f..9fd7faa735 100644 --- a/app/helpers/timelog_helper.rb +++ b/app/helpers/timelog_helper.rb @@ -81,7 +81,6 @@ module TimelogHelper end def entries_to_csv(entries) - ic = Iconv.new(l(:general_csv_encoding), 'UTF-8') decimal_separator = l(:general_csv_decimal_separator) custom_fields = TimeEntryCustomField.find(:all) export = FCSV.generate(:col_sep => l(:general_csv_separator)) do |csv| @@ -99,7 +98,7 @@ module TimelogHelper # Export custom fields headers += custom_fields.collect(&:name) - csv << headers.collect {|c| begin; ic.iconv(c.to_s); rescue; c.to_s; end } + csv << headers.collect {|c| begin; c.to_s.encode(l(:general_csv_encoding), 'UTF-8'); rescue; c.to_s; end } # csv lines entries.each do |entry| fields = [format_date(entry.spent_on), @@ -114,7 +113,7 @@ module TimelogHelper ] fields += custom_fields.collect {|f| show_value(entry.custom_value_for(f)) } - csv << fields.collect {|c| begin; ic.iconv(c.to_s); rescue; c.to_s; end } + csv << fields.collect {|c| begin; c.to_s.encode(l(:general_csv_encoding), 'UTF-8'); rescue; c.to_s; end } end end export @@ -181,8 +180,7 @@ module TimelogHelper end def to_utf8_for_timelogs(s) - @ic ||= Iconv.new(l(:general_csv_encoding), 'UTF-8') - begin; @ic.iconv(s.to_s); rescue; s.to_s; end + begin; s.to_s.encode(l(:general_csv_encoding), 'UTF-8'); rescue; s.to_s; end end def polymorphic_time_entries_path(object) diff --git a/app/models/changeset.rb b/app/models/changeset.rb index bd97e3a54d..08161d4a06 100644 --- a/app/models/changeset.rb +++ b/app/models/changeset.rb @@ -12,8 +12,6 @@ # See doc/COPYRIGHT.rdoc for more details. #++ -require 'iconv' - class Changeset < ActiveRecord::Base belongs_to :repository belongs_to :user @@ -286,8 +284,8 @@ class Changeset < ActiveRecord::Base txtar = "" begin - txtar += Iconv.new('UTF-8', normalized_encoding).iconv(str) - rescue Iconv::IllegalSequence + txtar += str.encode('UTF-8', normalized_encoding) + rescue Encoding::InvalidByteSequenceError, Encoding::UndefinedConversionError txtar += $!.success str = '?' + $!.failed[1,$!.failed.length] retry diff --git a/app/models/ldap_auth_source.rb b/app/models/ldap_auth_source.rb index 38c485a40f..4a7e446ef6 100644 --- a/app/models/ldap_auth_source.rb +++ b/app/models/ldap_auth_source.rb @@ -13,7 +13,6 @@ #++ require 'net/ldap' -require 'iconv' class LdapAuthSource < AuthSource validates_presence_of :host, :port, :attr_login diff --git a/config/database.yml.example b/config/database.yml.example index 3630273896..548a4510fe 100644 --- a/config/database.yml.example +++ b/config/database.yml.example @@ -29,10 +29,11 @@ test: test_pgsql: adapter: postgresql + encoding: unicode database: chiliproject_test - host: localhost - username: postgres - password: "postgres" + pool: 5 + username: chiliproject + password: test_sqlite3: adapter: sqlite3 diff --git a/config/initializers/bullet.rb b/config/initializers/bullet.rb index 6521eba5c1..50e8e13bd6 100644 --- a/config/initializers/bullet.rb +++ b/config/initializers/bullet.rb @@ -3,7 +3,7 @@ if defined?(Bullet) && Rails.env.development? config.after_initialize do Bullet.enable = true # Bullet.alert = true - Bullet.bullet_logger = true + Bullet.bullet_logger = true if File.directory?('log') # fails if run from an engine Bullet.console = true # Bullet.growl = true Bullet.rails_logger = true diff --git a/lib/redmine/export/pdf.rb b/lib/redmine/export/pdf.rb index 4fc04acf1c..6451738028 100644 --- a/lib/redmine/export/pdf.rb +++ b/lib/redmine/export/pdf.rb @@ -12,7 +12,6 @@ # See doc/COPYRIGHT.rdoc for more details. #++ -require 'iconv' require 'rfpdf/fpdf' require 'fpdf/chinese' require 'fpdf/japanese' @@ -43,7 +42,7 @@ module Redmine def SetTitle(txt) txt = begin - utf16txt = Iconv.conv('UTF-16BE', 'UTF-8', txt) + utf16txt = txt.to_s.encode('UTF-16BE', 'UTF-8') hextxt = "" @@ -118,7 +117,7 @@ module Redmine def SetTitle(txt) txt = begin - utf16txt = Iconv.conv('UTF-16BE', 'UTF-8', txt) + utf16txt = txt.to_s.encode('UTF-16BE', 'UTF-8') hextxt = "" @@ -138,14 +137,13 @@ module Redmine end def fix_text_encoding(txt) - @ic ||= Iconv.new(l(:general_pdf_encoding), 'UTF-8') # these quotation marks are not correctly rendered in the pdf txt = txt.gsub(/[“�]/, '"') if txt txt = begin # 0x5c char handling txtar = txt.split('\\') txtar << '' if txt[-1] == ?\\ - txtar.collect {|x| @ic.iconv(x)}.join('\\').gsub(/\\/, "\\\\\\\\") + txtar.collect {|x| x.encode(l(:general_pdf_encoding), 'UTF-8')}.join('\\').gsub(/\\/, "\\\\\\\\") rescue txt end || '' diff --git a/lib/redmine/scm/adapters/abstract_adapter.rb b/lib/redmine/scm/adapters/abstract_adapter.rb index 84a1835753..2c482f7658 100644 --- a/lib/redmine/scm/adapters/abstract_adapter.rb +++ b/lib/redmine/scm/adapters/abstract_adapter.rb @@ -225,12 +225,12 @@ module Redmine self.class.strip_credential(cmd) end - def scm_iconv(to, from, str) + def scm_encode(to, from, str) return nil if str.nil? return str if to == from begin - Iconv.conv(to, from, str) - rescue Iconv::Failure => err + str.to_s.encode(to, from) + rescue Encoding::InvalidByteSequenceError, Encoding::UndefinedConversionError => err logger.error("failed to convert from #{from} to #{to}. #{err}") nil end diff --git a/lib/redmine/scm/adapters/filesystem_adapter.rb b/lib/redmine/scm/adapters/filesystem_adapter.rb index ba7709a454..986cc3bdc6 100644 --- a/lib/redmine/scm/adapters/filesystem_adapter.rb +++ b/lib/redmine/scm/adapters/filesystem_adapter.rb @@ -51,23 +51,23 @@ module Redmine def entries(path="", identifier=nil) entries = Entries.new trgt_utf8 = target(path) - trgt = scm_iconv(@path_encoding, 'UTF-8', trgt_utf8) + trgt = scm_encode(@path_encoding, 'UTF-8', trgt_utf8) Dir.new(trgt).each do |e1| - e_utf8 = scm_iconv('UTF-8', @path_encoding, e1) + e_utf8 = scm_encode('UTF-8', @path_encoding, e1) next if e_utf8.blank? relative_path_utf8 = format_path_ends( (format_path_ends(path,false,true) + e_utf8),false,false) t1_utf8 = target(relative_path_utf8) - t1 = scm_iconv(@path_encoding, 'UTF-8', t1_utf8) - relative_path = scm_iconv(@path_encoding, 'UTF-8', relative_path_utf8) - e1 = scm_iconv(@path_encoding, 'UTF-8', e_utf8) + t1 = scm_encode(@path_encoding, 'UTF-8', t1_utf8) + relative_path = scm_encode(@path_encoding, 'UTF-8', relative_path_utf8) + e1 = scm_encode(@path_encoding, 'UTF-8', e_utf8) if File.exist?(t1) and # paranoid test %w{file directory}.include?(File.ftype(t1)) and # avoid special types not File.basename(e1).match(/^\.+$/) # avoid . and .. p1 = File.readable?(t1) ? relative_path : "" - utf_8_path = scm_iconv('UTF-8', @path_encoding, p1) + utf_8_path = scm_encode('UTF-8', @path_encoding, p1) entries << - Entry.new({ :name => scm_iconv('UTF-8', @path_encoding, File.basename(e1)), + Entry.new({ :name => scm_encode('UTF-8', @path_encoding, File.basename(e1)), # below : list unreadable files, but dont link them. :path => utf_8_path, :kind => (File.directory?(t1) ? 'dir' : 'file'), @@ -84,7 +84,7 @@ module Redmine end def cat(path, identifier=nil) - p = scm_iconv(@path_encoding, 'UTF-8', target(path)) + p = scm_encode(@path_encoding, 'UTF-8', target(path)) File.new(p, "rb").read rescue => err logger.error "scm: filesystem: error: #{err.message}" diff --git a/lib/redmine/scm/adapters/git_adapter.rb b/lib/redmine/scm/adapters/git_adapter.rb index 3165beabcd..2872194e36 100644 --- a/lib/redmine/scm/adapters/git_adapter.rb +++ b/lib/redmine/scm/adapters/git_adapter.rb @@ -105,7 +105,7 @@ module Redmine def entries(path=nil, identifier=nil) path ||= '' - p = scm_iconv(@path_encoding, 'UTF-8', path) + p = scm_encode(@path_encoding, 'UTF-8', path) entries = Entries.new cmd_args = %w|ls-tree -l| cmd_args << "HEAD:#{p}" if identifier.nil? @@ -122,8 +122,8 @@ module Redmine name.force_encoding(@path_encoding) end 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) + n = scm_encode('UTF-8', @path_encoding, name) + full_p = scm_encode('UTF-8', @path_encoding, full_path) entries << Entry.new({:name => n, :path => full_p, :kind => (type == "tree") ? 'dir' : 'file', @@ -177,7 +177,7 @@ module Redmine from_to << "#{identifier_to}" if identifier_to cmd_args << from_to if !from_to.empty? cmd_args << "--since=#{options[:since].strftime("%Y-%m-%d %H:%M:%S")}" if options[:since] - cmd_args << "--" << scm_iconv(@path_encoding, 'UTF-8', path) if path && !path.empty? + cmd_args << "--" << scm_encode(@path_encoding, 'UTF-8', path) if path && !path.empty? scm_cmd *cmd_args do |io| files=[] @@ -223,14 +223,14 @@ module Redmine parsing_descr = 2 fileaction = $1 filepath = $2 - p = scm_iconv('UTF-8', @path_encoding, filepath) + p = scm_encode('UTF-8', @path_encoding, filepath) files << {:action => fileaction, :path => p} elsif (parsing_descr == 1 || parsing_descr == 2) \ && line =~ /^:\d+\s+\d+\s+[0-9a-f.]+\s+[0-9a-f.]+\s+(\w)\d+\s+(\S+)\t(.+)$/ parsing_descr = 2 fileaction = $1 filepath = $3 - p = scm_iconv('UTF-8', @path_encoding, filepath) + p = scm_encode('UTF-8', @path_encoding, filepath) files << {:action => fileaction, :path => p} elsif (parsing_descr == 1) && line.chomp.to_s == "" parsing_descr = 2 @@ -269,7 +269,7 @@ module Redmine else cmd_args << "show" << "--no-color" << identifier_from end - cmd_args << "--" << scm_iconv(@path_encoding, 'UTF-8', path) unless path.empty? + cmd_args << "--" << scm_encode(@path_encoding, 'UTF-8', path) unless path.empty? diff = [] scm_cmd *cmd_args do |io| io.each_line do |line| @@ -284,7 +284,7 @@ module Redmine def annotate(path, identifier=nil) identifier = 'HEAD' if identifier.blank? cmd_args = %w|blame| - cmd_args << "-p" << identifier << "--" << scm_iconv(@path_encoding, 'UTF-8', path) + cmd_args << "-p" << identifier << "--" << scm_encode(@path_encoding, 'UTF-8', path) blame = Annotate.new content = nil scm_cmd(*cmd_args) { |io| io.binmode; content = io.read } @@ -321,7 +321,7 @@ module Redmine identifier = 'HEAD' end cmd_args = %w|show --no-color| - cmd_args << "#{identifier}:#{scm_iconv(@path_encoding, 'UTF-8', path)}" + cmd_args << "#{identifier}:#{scm_encode(@path_encoding, 'UTF-8', path)}" cat = nil scm_cmd(*cmd_args) do |io| io.binmode diff --git a/lib/redmine/scm/adapters/mercurial_adapter.rb b/lib/redmine/scm/adapters/mercurial_adapter.rb index c6c7efa1a3..bb090e3876 100644 --- a/lib/redmine/scm/adapters/mercurial_adapter.rb +++ b/lib/redmine/scm/adapters/mercurial_adapter.rb @@ -130,7 +130,7 @@ module Redmine private :summary def entries(path=nil, identifier=nil) - p1 = scm_iconv(@path_encoding, 'UTF-8', path) + p1 = scm_encode(@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 @@ -146,13 +146,13 @@ module Redmine entries = Entries.new as_ary(manifest['dir']).each do |e| - n = scm_iconv('UTF-8', @path_encoding, CGI.unescape(e['name'])) + n = scm_encode('UTF-8', @path_encoding, CGI.unescape(e['name'])) p = "#{path_prefix}#{n}" entries << Entry.new(:name => n, :path => p, :kind => 'dir') end as_ary(manifest['file']).each do |e| - n = scm_iconv('UTF-8', @path_encoding, CGI.unescape(e['name'])) + n = scm_encode('UTF-8', @path_encoding, CGI.unescape(e['name'])) p = "#{path_prefix}#{n}" lr = Revision.new(:revision => e['revision'], :scmid => e['node'], :identifier => e['node'], @@ -194,13 +194,13 @@ module Redmine as_ary(log['logentry']).each do |le| cpalist = as_ary(le['paths']['path-copied']).map do |e| [e['__content__'], e['copyfrom-path']].map do |s| - scm_iconv('UTF-8', @path_encoding, CGI.unescape(s)) + scm_encode('UTF-8', @path_encoding, CGI.unescape(s)) end end cpmap = Hash[*cpalist.flatten] paths = as_ary(le['paths']['path']).map do |e| - p = scm_iconv('UTF-8', @path_encoding, CGI.unescape(e['__content__']) ) + p = scm_encode('UTF-8', @path_encoding, CGI.unescape(e['__content__']) ) {:action => e['action'], :path => with_leading_slash(p), :from_path => (cpmap.member?(p) ? with_leading_slash(cpmap[p]) : nil), :from_revision => (cpmap.member?(p) ? le['revision'] : nil)} @@ -233,7 +233,7 @@ module Redmine hg_args << '-c' << hgrev(identifier_from) end unless path.blank? - p = scm_iconv(@path_encoding, 'UTF-8', path) + p = scm_encode(@path_encoding, 'UTF-8', path) hg_args << CGI.escape(hgtarget(p)) end diff = [] @@ -248,7 +248,7 @@ module Redmine end def cat(path, identifier=nil) - p = CGI.escape(scm_iconv(@path_encoding, 'UTF-8', path)) + p = CGI.escape(scm_encode(@path_encoding, 'UTF-8', path)) hg 'rhcat', '-r', CGI.escape(hgrev(identifier)), hgtarget(p) do |io| io.binmode io.read @@ -258,7 +258,7 @@ module Redmine end def annotate(path, identifier=nil) - p = CGI.escape(scm_iconv(@path_encoding, 'UTF-8', path)) + p = CGI.escape(scm_encode(@path_encoding, 'UTF-8', path)) blame = Annotate.new hg 'rhannotate', '-ncu', '-r', CGI.escape(hgrev(identifier)), hgtarget(p) do |io| io.each_line do |line| diff --git a/lib/tasks/migrate_from_mantis.rake b/lib/tasks/migrate_from_mantis.rake index 80491f3a22..9ed3670029 100644 --- a/lib/tasks/migrate_from_mantis.rake +++ b/lib/tasks/migrate_from_mantis.rake @@ -16,7 +16,6 @@ desc 'Mantis migration script' require 'active_record' -require 'iconv' require 'pp' namespace :redmine do @@ -439,9 +438,9 @@ task :migrate_from_mantis => :environment do end def self.encoding(charset) - @ic = Iconv.new('UTF-8', charset) - rescue Iconv::InvalidEncoding - return false + ''.encode('UTF-8', @encoding = charset) + rescue Encoding::ConverterNotFoundError + false end def self.establish_connection(params) @@ -453,7 +452,8 @@ task :migrate_from_mantis => :environment do end def self.encode(text) - @ic.iconv text + @encoding ||= 'UTF-8' + text.encode('UTF-8', @encoding) rescue text end diff --git a/lib/tasks/migrate_from_trac.rake b/lib/tasks/migrate_from_trac.rake index 62c7f8df09..31c8bb0812 100644 --- a/lib/tasks/migrate_from_trac.rake +++ b/lib/tasks/migrate_from_trac.rake @@ -14,7 +14,6 @@ require 'active_record' -require 'iconv' require 'pp' namespace :redmine do @@ -597,10 +596,10 @@ namespace :redmine do end def self.encoding(charset) - @ic = Iconv.new('UTF-8', charset) - rescue Iconv::InvalidEncoding + ''.encode('UTF-8', @encoding = charset) + rescue Encoding::ConverterNotFoundError puts "Invalid encoding!" - return false + false end def self.set_trac_directory(path) @@ -709,7 +708,8 @@ namespace :redmine do private def self.encode(text) - @ic.iconv text + @encoding ||= 'UTF-8' + text.encode('UTF-8', @encoding) rescue text end diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb new file mode 100644 index 0000000000..73a0fa76d4 --- /dev/null +++ b/spec/models/project_spec.rb @@ -0,0 +1,27 @@ +require 'spec_helper' + +describe Project do + describe Project::STATUS_ACTIVE do + it "equals 1" do + # spec that STATUS_ACTIVE has the correct value + Project::STATUS_ACTIVE.should == 1 + end + end + + describe "#active?" do + before do + # stub out the actual value of the constant + stub_const('Project::STATUS_ACTIVE', 42) + end + + it "is active when :status equals STATUS_ACTIVE" do + project = FactoryGirl.create :project, :status => 42 + project.should be_active + end + + it "is not active when :status doesn't equal STATUS_ACTIVE" do + project = FactoryGirl.create :project, :status => 99 + project.should_not be_active + end + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index c0838323f0..25dcc69f67 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,39 +1,89 @@ -# This file is copied to spec/ when you run 'rails generate rspec:install' -ENV["RAILS_ENV"] ||= 'test' -require File.expand_path("../../config/environment", __FILE__) -require 'rspec/rails' -require 'rspec/autorun' -require 'capybara/rails' - -# Requires supporting ruby files with custom matchers and macros, etc, -# in spec/support/ and its subdirectories. -Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f} - -RSpec.configure do |config| - # ## Mock Framework - # - # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line: - # - # config.mock_with :mocha - # config.mock_with :flexmock - # config.mock_with :rr - - # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures - config.fixture_path = "#{::Rails.root}/spec/fixtures" - - # If you're not using ActiveRecord, or you'd prefer not to run each of your - # examples within a transaction, remove the following line or assign false - # instead of true. - config.use_transactional_fixtures = true - - # If true, the base class of anonymous controllers will be inferred - # automatically. This will be the default behavior in future versions of - # rspec-rails. - config.infer_base_class_for_anonymous_controllers = false - - # Run specs in random order to surface order dependencies. If you find an - # order dependency and want to debug it, you can fix the order by providing - # the seed, which is printed after each run. - # --seed 1234 - config.order = "random" +# --- Instructions --- +# Sort the contents of this file into a Spork.prefork and a Spork.each_run +# block. +# +# The Spork.prefork block is run only once when the spork server is started. +# You typically want to place most of your (slow) initializer code in here, in +# particular, require'ing any 3rd-party gems that you don't normally modify +# during development. +# +# The Spork.each_run block is run each time you run your specs. In case you +# need to load files that tend to change during development, require them here. +# With Rails, your application modules are loaded automatically, so sometimes +# this block can remain empty. +# +# Note: You can modify files loaded *from* the Spork.each_run block without +# restarting the spork server. However, this file itself will not be reloaded, +# so if you change any of the code inside the each_run block, you still need to +# restart the server. In general, if you have non-trivial code in this file, +# it's advisable to move it into a separate file so you can easily edit it +# without restarting spork. (For example, with RSpec, you could move +# non-trivial code into a file spec/support/my_helper.rb, making sure that the +# spec/support/* files are require'd from inside the each_run block.) +# +# Any code that is left outside the two blocks will be run during preforking +# *and* during each_run -- that's probably not what you want. +# +# These instructions should self-destruct in 10 seconds. If they don't, feel +# free to delete them. + +require 'rubygems' +require 'spork' + +#uncomment the following line to use spork with the debugger +#require 'spork/ext/ruby-debug' + +Spork.prefork do + # Loading more in this block will cause your tests to run faster. However, + # if you change any configuration or code from libraries loaded here, you'll + # need to restart spork for it take effect. + + # This file is copied to spec/ when you run 'rails generate rspec:install' + ENV["RAILS_ENV"] ||= 'test' + require File.expand_path("../../config/environment", __FILE__) + require 'rspec/rails' + require 'rspec/autorun' + require 'capybara/rails' + + # Requires supporting ruby files with custom matchers and macros, etc, + # in spec/support/ and its subdirectories. + Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f} + + RSpec.configure do |config| + # ## Mock Framework + # + # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line: + # + # config.mock_with :mocha + # config.mock_with :flexmock + # config.mock_with :rr + + # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures + config.fixture_path = "#{::Rails.root}/spec/fixtures" + + # If you're not using ActiveRecord, or you'd prefer not to run each of your + # examples within a transaction, remove the following line or assign false + # instead of true. + config.use_transactional_fixtures = true + + # If true, the base class of anonymous controllers will be inferred + # automatically. This will be the default behavior in future versions of + # rspec-rails. + config.infer_base_class_for_anonymous_controllers = false + + # Run specs in random order to surface order dependencies. If you find an + # order dependency and want to debug it, you can fix the order by providing + # the seed, which is printed after each run. + # --seed 1234 + config.order = "random" + + config.treat_symbols_as_metadata_keys_with_true_values = true + config.filter_run :focus => true + config.run_all_when_everything_filtered = true + end +end + +Spork.each_run do + # This code will be run each time you run your specs. + FactoryGirl.reload end