## 1.8/library/iconv/fixtures/utf16.rb module IconvSpecs def self.utf16be(item) item end def self.utf16le(item) if item.kind_of?(String) item.gsub(/(.)(.)/, '\2\1') else item.collect { |s| utf16le(s) } end end class << self big_endian do alias_method :utf16, :utf16be end little_endian do # a very hacky workaround platform_is :windows do alias_method :utf16, :utf16be end platform_is_not :windows do alias_method :utf16, :utf16le end end end end ## 1.8/library/iconv/iconv_spec.rb require File.dirname(__FILE__) + '/../../spec_helper' require File.dirname(__FILE__) + '/shared/initialize_exceptions' require File.dirname(__FILE__) + '/fixtures/utf16' require 'iconv' # These specs assume the Iconv implementation supports at least # the following encodings: # us-ascii, utf-8, utf-16, utf-16be, utf-16le, iso-8859-1 describe "Iconv#iconv" do it "raises an ArgumentError when called on a closed converter" do conv = Iconv.new("us-ascii", "us-ascii") conv.close lambda { conv.iconv("test") }.should raise_error(ArgumentError) end it "when given a string or string-like parameter returns a converted version of it" do Iconv.open "utf-8", "iso-8859-1" do |conv| conv.iconv("expos\xe9").should == "expos\xc3\xa9" stringlike = mock("string-like") stringlike.should_receive(:to_str).and_return("r\xe9sum\xe9") conv.iconv(stringlike).should == "r\xc3\xa9sum\xc3\xa9" end end it "keeps context between calls" do Iconv.open "utf-16", "us-ascii" do |conv| # BOM for first call of utf-16 conv.iconv("a").should == IconvSpecs.utf16("\xfe\xff\0a") # no BOM for consecutive calls conv.iconv("a").should == IconvSpecs.utf16("\0a") end end it "when given nil resets the converter" do Iconv.open "utf-16", "utf-8" do |conv| conv.iconv("a").should == IconvSpecs.utf16("\xfe\xff\0a") conv.iconv("a").should == IconvSpecs.utf16("\0a") conv.iconv(nil) conv.iconv("a").should == IconvSpecs.utf16("\xfe\xff\0a") end end it "when given a negative start position counts from the end of string" do Iconv.open "us-ascii", "us-ascii" do |conv| conv.iconv("testing", -7, 4).should == "test" conv.iconv("testing", -3, 7).should == "ing" end end it "when the end parameter is omitted or nil goes until the end of the string" do Iconv.open "us-ascii", "us-ascii" do |conv| conv.iconv("testing", 0).should == "testing" conv.iconv("testing", 4).should == "ing" conv.iconv("testing", 4, nil).should == "ing" conv.iconv("testing", -3).should == "ing" conv.iconv("testing", -4, nil).should == "ting" end end it "when given a positive end position treats it as exclusive" do # i.e. string[start...end] Iconv.open "us-ascii", "us-ascii" do |conv| conv.iconv("testing", 0, 4).should == "test" conv.iconv("testing", 4, 6).should == "in" conv.iconv("substring", -6, 6).should == "str" end end it "when given a negative end position treats it as inclusive" do # i.e. string[start..end] Iconv.open "us-ascii", "us-ascii" do |conv| conv.iconv("testing", 0, -1).should == "testing" conv.iconv("testing", 2, -4).should == "st" conv.iconv("substring", -6, -4).should == "str" end end it "to utf-16, when given an empty string or empty range, always returns an empty string" do Iconv.open "utf-16", "utf-8" do |conv| conv.iconv("").should == "" # no BOM conv.iconv("test", 0, 0).should == "" conv.iconv("test", 2, -3).should == "" conv.iconv("test", 3, 2).should == "" conv.iconv("test", 1, -4).should == "" end end it "raises Iconv::IllegalSequence when faced with an invalid byte" do Iconv.open "us-ascii", "us-ascii" do |conv| lambda { conv.iconv("test\xa0") }.should raise_error(Iconv::IllegalSequence) end Iconv.open "utf-8", "utf-8" do |conv| lambda { conv.iconv("test\x80") }.should raise_error(Iconv::IllegalSequence) end end it "raises Iconv::IllegalSequence when a character cannot be represented on the target encoding" do Iconv.open "us-ascii", "utf-8" do |conv| lambda { conv.iconv("euro \xe2\x82\xac") }.should raise_error(Iconv::IllegalSequence) end end it "raises Iconv::InvalidCharacter when an incomplete character or shift sequence happens at the end of the input buffer" do Iconv.open "utf-8", "utf-8" do |conv| lambda { conv.iconv("euro \xe2") }.should raise_error(Iconv::InvalidCharacter) lambda { conv.iconv("euro \xe2\x82") }.should raise_error(Iconv::InvalidCharacter) end Iconv.open "utf-16be", "utf-16be" do |conv| lambda { conv.iconv("a") }.should raise_error(Iconv::InvalidCharacter) end end it "ignores characters which cannot be represented in the target encoding when the //ignore option is set for the target encoding" do Iconv.open "iso-8859-1//ignore", "utf-8" do |conv| conv.iconv("euro \xe2\x82\xac euro").should == "euro euro" end end it "transliterates characters which cannot be accurately represented in the target encoding when the //translit option is set for the target encoding" do # hard to test this one, seems too implementation-dependent on # the platform's iconv(3) library platform_is :os => :linux do Iconv.open "us-ascii//translit", "utf-16be" do |conv| conv.iconv("\xff\xfd").should == "?" end end end ruby_bug "#17910" do it "sanitizes invalid upper bounds" do Iconv.open "us-ascii", "us-ascii" do |conv| conv.iconv("testing", 0, 99).should == "testing" conv.iconv("testing", 10, 12).should == "" end end end it "returns a blank string on invalid lower bounds" do Iconv.open "us-ascii", "us-ascii" do |conv| conv.iconv("testing", -10, -8).should == "" conv.iconv("testing", -8).should == "" conv.iconv("testing", -9, 5).should == "" end end end describe "Iconv.iconv" do it "converts a series of strings with a single converter" do # BOM only on first string Iconv.iconv("utf-16", "utf-8", "abc", "de").should == IconvSpecs.utf16(["\xfe\xff\0a\0b\0c", "\0d\0e"]) end it "returns an empty array when given no strings to convert" do Iconv.iconv("us-ascii", "utf-8").should == [] end it "acts exactly as if invoking Iconv#iconv consecutively on the same converter" do Iconv.iconv("utf-16", "utf-8", "a", "b", "c", nil, "d", "e").should == IconvSpecs.utf16(["\xfe\xff\0a", "\0b", "\0c", "", "\xfe\xff\0d", "\0e"]) end it_behaves_like :iconv_initialize_exceptions, :iconv, "test" end ## 1.8/library/iconv/close_spec.rb require File.dirname(__FILE__) + '/../../spec_helper' require 'iconv' describe "Iconv#close" do it "fails silently if called more than once" do conv1 = Iconv.new("us-ascii", "us-ascii") lambda { conv1.close conv1.close }.should_not raise_error lambda { Iconv.open "us-ascii", "us-ascii" do |conv2| conv2.close end }.should_not raise_error end # return values of #close not tested yet end ## 1.8/library/iconv/failure/success_spec.rb require File.dirname(__FILE__) + '/../../../spec_helper' require 'iconv' describe "Iconv::Failure#success" do it "for Iconv#iconv and Iconv.conv returns the substring of the original string passed which was translated successfully until the exception ocurred" do lambda { begin Iconv.open "us-ascii", "us-ascii" do |conv| conv.iconv "test \xff test \xff" end rescue Iconv::Failure => e @ex = e raise e end }.should raise_error(Iconv::Failure) @ex.success.should == "test " lambda { begin Iconv.conv "utf-8", "utf-8", "\xe2\x82" rescue Iconv::Failure => e @ex = e raise e end }.should raise_error(Iconv::Failure) @ex.success.should == "" end it "for Iconv.iconv returns an array containing all the strings that were translated successfully until the exception ocurred, in order" do lambda { begin Iconv.iconv("us-ascii", "us-ascii", "\xfferror") rescue Iconv::Failure => e @ex = e raise e end }.should raise_error(Iconv::Failure) @ex.success.should == [""] lambda { begin Iconv.iconv("us-ascii", "us-ascii", "test", "testing", "until\xfferror") rescue Iconv::Failure => e @ex = e raise e end }.should raise_error(Iconv::Failure) @ex.success.should == ["test", "testing", "until"] end end ## 1.8/library/iconv/failure/inspect_spec.rb require File.dirname(__FILE__) + '/../../../spec_helper' require 'iconv' describe "Iconv::Failure#inspect" do it "includes information on the exception class name, #succes and #failed" do lambda { begin Iconv.open "utf-8", "utf-8" do |conv| conv.iconv "testing string \x80 until an error occurred" end rescue Iconv::Failure => e @ex = e raise e end }.should raise_error(Iconv::Failure) inspection = @ex.inspect inspection.should MSpec.include(@ex.class.to_s) inspection.should MSpec.include(@ex.success.inspect) inspection.should MSpec.include(@ex.failed.inspect) end end ## 1.8/library/iconv/failure/failed_spec.rb require File.dirname(__FILE__) + '/../../../spec_helper' require 'iconv' describe "Iconv::Failure#failed" do it "returns a substring of the original string passed to Iconv that starts at the character which caused the exception" do lambda { begin Iconv.open "us-ascii", "us-ascii" do |conv| conv.iconv "test \xff test \xff" end rescue Iconv::Failure => e @ex = e raise e end }.should raise_error(Iconv::Failure) @ex.failed.should == "\xff test \xff" lambda { begin Iconv.open "utf-8", "utf-8" do |conv| conv.iconv "test \xe2\x82" end rescue Iconv::Failure => e @ex = e raise e end }.should raise_error(Iconv::Failure) @ex.failed.should == "\xe2\x82" end it "for Iconv.iconv and Iconv.conv returns an array containing a single element when instantiated" do lambda { begin Iconv.iconv("us-ascii", "us-ascii", "test \xff test") rescue Iconv::Failure => e @ex = e raise e end }.should raise_error(Iconv::Failure) @ex.failed.should == ["\xff test"] lambda { begin Iconv.conv("us-ascii", "us-ascii", "test \xff test") rescue Iconv::Failure => e @ex = e raise e end }.should raise_error(Iconv::Failure) @ex.failed.should == ["\xff test"] end end ## 1.8/library/iconv/charset_map_spec.rb require File.dirname(__FILE__) + '/../../spec_helper' require 'iconv' describe "Iconv.charset_map" do it "acts as a map" do Iconv.charset_map.respond_to?(:[]).should be_true end end ## 1.8/library/iconv/shared/new.rb require File.dirname(__FILE__) + '/initialize_exceptions.rb' shared :iconv_new do |cmd| describe "Iconv.#{cmd}" do it "creates a new encoding converter" do obj = Iconv.send(cmd, "us-ascii", "us-ascii") begin obj.should be_kind_of(Iconv) ensure obj.close end end it_behaves_like :iconv_initialize_exceptions, cmd end end ## 1.8/library/iconv/shared/initialize_exceptions.rb shared :iconv_initialize_exceptions do |cmd, *args| describe "Iconv.#{cmd}" do it "raises a TypeError when encoding names are not Strings or string-compatible" do lambda { Iconv.send cmd, Object.new, "us-ascii", *args }.should raise_error(TypeError) lambda { Iconv.send cmd, "us-ascii", Object.new, *args }.should raise_error(TypeError) end it "raises an Iconv::InvalidEncoding exception when an encoding cannot be found" do lambda { Iconv.send cmd, "x-nonexistent-encoding", "us-ascii", *args }.should raise_error(Iconv::InvalidEncoding) end end end ## 1.8/library/iconv/new_spec.rb require File.dirname(__FILE__) + '/../../spec_helper' require File.dirname(__FILE__) + '/shared/new' require 'iconv' describe "Iconv.new" do it_behaves_like :iconv_new, :new end ## 1.8/library/iconv/conv_spec.rb require File.dirname(__FILE__) + '/../../spec_helper' require File.dirname(__FILE__) + '/shared/initialize_exceptions' require File.dirname(__FILE__) + '/fixtures/utf16' require 'iconv' describe "Iconv.conv" do it_behaves_like :iconv_initialize_exceptions, :conv, "test" it "acts exactly as if opening a converter and invoking #iconv once" do Iconv.conv("utf-8", "iso-8859-1", "expos\xe9").should == "expos\xc3\xa9" stringlike = mock("string-like") stringlike.should_receive(:to_str).and_return("cacha\xc3\xa7a") Iconv.conv("iso-8859-1", "utf-8", stringlike).should == "cacha\xe7a" Iconv.conv("utf-16", "us-ascii", "a").should == IconvSpecs.utf16("\xfe\xff\0a") # each call is completely independent; never retain context! Iconv.conv("utf-16", "us-ascii", "b").should == IconvSpecs.utf16("\xfe\xff\0b") Iconv.conv("us-ascii", "iso-8859-1", nil).should == "" Iconv.conv("utf-16", "utf-8", "").should == "" lambda { Iconv.conv("us-ascii", "us-ascii", "test\xa9") }.should raise_error(Iconv::IllegalSequence) lambda { Iconv.conv("utf-8", "utf-8", "euro \xe2") }.should raise_error(Iconv::InvalidCharacter) Iconv.conv("iso-8859-1//ignore", "utf-8", "euro \xe2\x82\xac euro").should == "euro euro" end end ## 1.8/library/iconv/failure_spec.rb require File.dirname(__FILE__) + '/../../spec_helper' require 'iconv' describe "Iconv::Failure" do it "is a module" do Iconv::Failure.should be_kind_of(Module) Iconv::Failure.should_not be_kind_of(Class) end it "is included by Iconv::InvalidEncoding" do Iconv::Failure.should be_ancestor_of(Iconv::InvalidEncoding) end it "is included by Iconv::IllegalSequence" do Iconv::Failure.should be_ancestor_of(Iconv::IllegalSequence) end it "is included by Iconv::InvalidCharacter" do Iconv::Failure.should be_ancestor_of(Iconv::InvalidCharacter) end it "is included by Iconv::OutOfRange" do Iconv::Failure.should be_ancestor_of(Iconv::OutOfRange) end it "is included by Iconv::BrokenLibrary" do Iconv::Failure.should be_ancestor_of(Iconv::BrokenLibrary) end end ## 1.8/library/iconv/open_spec.rb require File.dirname(__FILE__) + '/../../spec_helper' require File.dirname(__FILE__) + '/shared/new' require 'iconv' describe "Iconv.open" do it_behaves_like :iconv_new, :open it "with a block invokes the block exactly once" do count = 0 Iconv.open "us-ascii", "us-ascii" do count += 1 end count.should == 1 end it "with a block yields the converter" do Iconv.open "us-ascii", "us-ascii" do |conv| conv.should be_kind_of(Iconv) end end it "with a block returns the result of the block" do Iconv.open("us-ascii", "us-ascii") { "block return value" }.should == "block return value" end # not testable with the current API: # it "with a block always closes the converter when exiting the block" end