2013-02-12 58 views
5

這種語言Iconv成語轉碼字符串爲UTF-8並丟棄不能音譯字符:你會如何寫的`Iconv.new( 「UTF8 //忽略」,...)`成語測試?

require "iconv" 

def normalize(text) 
    Iconv.new('UTF-8//IGNORE', 'UTF-8').iconv(text.dup) 
end 

你將如何實際編寫了這個測試?

編輯:我最終簡化了這個問題,因爲我意識到試圖在Rails # encoding: utf-8 spec文件中測試這個問題的上下文使問題變得複雜。所以,現在的賞金是一種愚蠢,但我反正獎勵,如果有人可以顯示一個測試,我可以過的工作。

+0

也許,看看這個:HTTP:/ /robots.thoughtbot.com/post/42664369166/fight-back-utf-8-invalid-byte-sequences – Hock 2013-02-21 04:50:24

回答

3

可以從字節數組使用#pack方法構造字符串。這樣,您可以輕鬆生成無效/錯誤的字符串,並在測試中使用它。

例子:

describe "#normalize" do 
    it "should remove/ignore invalid characters" do 
    # this "string" equals "Mandados de busca do caso Megaupload considerados inv\xE1lidos - Tecnologia - Sol" 
    bad_string = [77, 97, 110, 100, 97, 100, 111, 115, 32, 100, 101, 32, 98, 117, 115, 99, 97, 32, 100, 111, 32, 99, 97, 115, 111, 32, 77, 101, 103, 97, 117, 112, 108, 111, 97, 100, 32, 99, 111, 110, 115, 105, 100, 101, 114, 97, 100, 111, 115, 32, 105, 110, 118, 225, 108, 105, 100, 111, 115, 32, 45, 32, 84, 101, 99, 110, 111, 108, 111, 103, 105, 97, 32, 45, 32, 83, 111, 108].pack('c*').force_encoding('UTF-8') 

    normalize(bad_string).should == 'Mandados de busca do caso Megaupload considerados invlidos - Tecnologia - Sol' 
    end 
end 

(我在相當長的測試字符串對不起,我只是找不到在我的代碼更短的例子)

+0

你可以在你的測試中解釋'force_encoding'的用途嗎?它會模仿通過'accept-charset = utf8'形式傳遞字符串的過程嗎? – danneu 2013-02-16 18:05:20

+0

是的,確切地說。你想用'normalize'方法實現的目標是將無效的utf8字符串轉換爲有效的字符串。所以爲了測試你的方法,你首先必須創建一個無效的utf8字符串。上面的方法是我找到的最簡單的方法:使用'pack'從字節集合中創建一個字符串,然後使用'force_encoding'將這個字符串標記爲utf8 ... – severin 2013-02-17 11:08:27

1

在軌測試此,即使有一個#encoding組是可能的。

只需使用一個編碼步驟一樣網址轉義:

require "iconv" 
require "cgi" 

def normalize(text) 
    Iconv.new('UTF-8//IGNORE', 'UTF-8').iconv(text) 
end 

puts normalize(CGI.unescape("m%FCstring")) # => mstring 

,以便與該你可以寫一個斷言。

當您使用Ruby 1.9的語言Iconv已被廢棄,你應該使用字符串的encode方法!

+0

是啊,這個問題的出現,因爲我想用'字符串#encode'更換語言Iconv對Ruby 2.0.0兼容性,我試圖抵禦迴歸。 – danneu 2013-02-14 23:53:46

+0

所以答案不適合你的問題?或者爲什麼除了你呢? – phoet 2013-02-16 09:30:23