Skip to content

Commit

Permalink
Stop Ruby 1.9 version depending on deprecated iconv
Browse files Browse the repository at this point in the history
  • Loading branch information
Joel Chippindale committed May 26, 2012
1 parent 13fb051 commit 3d8a4bb
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 18 deletions.
2 changes: 1 addition & 1 deletion csv_builder.gemspec
Expand Up @@ -50,7 +50,7 @@ Gem::Specification.new do |s|
s.homepage = %q{http://github.com/dasil003/csv_builder}
s.licenses = [%q{MIT}]
s.require_paths = [%q{lib}]
s.requirements = [%q{iconv}]
s.requirements = [%q{iconv or Ruby 1.9}]
s.rubygems_version = %q{1.8.6}
s.summary = %q{CSV template handler for Rails}

Expand Down
2 changes: 1 addition & 1 deletion lib/csv_builder.rb
Expand Up @@ -5,13 +5,13 @@ module CsvBuilder
require 'csv'
CSV_LIB = CSV
else
require 'iconv'
require 'fastercsv'
CSV_LIB = FasterCSV
end
end

require 'action_view'
require 'iconv'
require 'csv_builder/transliterating_filter'
require 'csv_builder/template_handler'
require 'csv_builder/railtie'
51 changes: 40 additions & 11 deletions lib/csv_builder/transliterating_filter.rb
@@ -1,26 +1,55 @@
#encoding: utf-8

# Transliterate into the required encoding if necessary
#
# We can't rely on the encoding option in the Ruby 1.9 version CSV because this
# is ignored when it is 'compatible' (see <tt>Encoding.compatible?</tt>with the
# input for example:
#
# CSV.generate(:encoding => 'ASCII') { |csv| '£12.34'.encoding('UTF-8') }
#
# will generate a UTF-8 encoded string.
class CsvBuilder::TransliteratingFilter
# Transliterate into the required encoding if necessary
def initialize(csv, input_encoding = 'UTF-8', output_encoding = 'ISO-8859-1')
self.csv = csv

# TODO: do some checking to make sure iconv works correctly in
# current environment. See ActiveSupport::Inflector#transliterate
# definition for details
#
# Not using the more standard //IGNORE//TRANSLIT because it raises
# Iconv::IllegalSequence for some inputs
self.iconv = Iconv.new("#{output_encoding}//TRANSLIT//IGNORE", input_encoding) if input_encoding != output_encoding
if RUBY_VERSION.to_f < 1.9
# TODO: do some checking to make sure iconv works correctly in
# current environment. See <tt>ActiveSupport::Inflector#transliterate</tt>
# definition for details
#
# Not using the more standard //IGNORE//TRANSLIT because it raises
# <tt>Iconv::IllegalSequence,/tt> for some inputs
self.iconv = Iconv.new("#{output_encoding}//TRANSLIT//IGNORE", input_encoding) if input_encoding != output_encoding
else
# <tt>input_encoding</tt> is ignored because we know what this it is
self.output_encoding = output_encoding
end
end

# Transliterate before passing to FasterCSV so that the right characters (e.g. quotes) get escaped
# Transliterate before passing to CSV so that the right characters
# (e.g. quotes) get escaped
def <<(row)
csv << if iconv then row.map { |value| iconv.iconv(value.to_s) } else row end
@csv << convert_row(row)
end

alias :add_row :<<

private
attr_accessor :csv, :iconv
attr_accessor :csv

private
if RUBY_VERSION.to_f < 1.9
attr_accessor :iconv

def convert_row(row)
if iconv then row.map { |value| iconv.iconv(value.to_s) } else row end
end
else
attr_accessor :output_encoding

def convert_row(row)
row.map { |value| value.to_s.encode(output_encoding, :undef => :replace) }
end
end
end
16 changes: 12 additions & 4 deletions spec/controllers/csv_builder_spec.rb
Expand Up @@ -62,16 +62,24 @@ def massive

describe "Layout with options" do
describe "output encoding" do
let(:expected_utf8) { generate({}, [['£12.34', 'ąčęėįšųūž', 'foo']]) }

if RUBY_VERSION.to_f < 1.9 && RUBY_PLATFORM.match(/darwin/)
# iconv appears to have more transliteration built into it on OSX than
# other platforms and so does a 'better' job of converting to ASCII
let(:expected_ascii) { generate({}, [['lb12.34' ,'aceeisuuz', 'foo']]) }
else
let(:expected_ascii) { generate({}, [['?12.34' ,'?????????', 'foo']]) }
end

it "transliterates to ASCII when required" do
get 'encoding', :format => 'csv', :encoding => 'ASCII'
correct_output = generate({}, [['aceeisuuz']])
response.body.to_s.should == correct_output
response.body.to_s.should == expected_ascii
end

it "keeps output in UTF-8 when required" do
get 'encoding', :format => 'csv', :encoding => 'UTF-8'
correct_output = generate({}, [['ąčęėįšųūž']])
response.body.to_s.should == correct_output
response.body.to_s.should == expected_utf8
end
end

Expand Down
2 changes: 1 addition & 1 deletion spec/templates/csv_builder_reports/encoding.csv.csvbuilder
@@ -1 +1 @@
csv << ['ąčęėįšųūž']
csv << ['£12.34', 'ąčęėįšųūž', 'foo']

0 comments on commit 3d8a4bb

Please sign in to comment.