【问题标题】:How would you write a test for the `Iconv.new("UTF8//IGNORE", ...)` idiom?您将如何为 `Iconv.new("UTF8//IGNORE", ...)` 习语编写测试?
【发布时间】:2013-02-12 00:22:42
【问题描述】:

此 Iconv 惯用语将字符串转码为 UTF-8 并丢弃无法音译的字符:

require "iconv"

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

您实际上会如何为此编写测试?

编辑:我最终简化了问题,因为我意识到尝试在 Rails # encoding: utf-8 规范文件中测试它的上下文使问题复杂化。所以现在赏金有点傻,但无论如何我都会奖励它,如果有人可以展示我可以完成的测试。

【问题讨论】:

标签: ruby-on-rails ruby character-encoding ruby-on-rails-3.2


【解决方案1】:

您可以使用#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

(对不起,测试字符串相当长,我只是在我的代码中找不到更短的示例)

【讨论】:

  • 你能解释一下force_encoding在你的测试中的用途吗?它会模拟通过accept-charset=utf8 表单或其他方式传递字符串的过程吗?
  • 是的,完全正确。您希望使用normalize 方法实现的目标是将无效的 utf8 字符串转换为有效字符串。因此,要测试您的方法,您首先必须创建一个无效的 utf8 字符串。上面的方法是我发现的最简单的方法:使用pack从字节集合创建一个字符串,然后force_encoding将此字符串标记为utf8 ...
【解决方案2】:

在 Rails 中对此进行测试,即使设置了 #encoding 也是可能的。

只需使用 URL 转义之类的编码步骤:

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 方法!

【讨论】:

  • 是的,这个问题的出现是因为我试图用 String#encode 替换 Iconv 以实现 Ruby 2.0.0 兼容性,并且我试图防御回归。
  • 所以答案不适合您的问题?或者你为什么不把它除外?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多