问题 Ruby缩进多行字符串[重复]


这个问题在这里已有答案:


5325
2017-07-28 07:13


起源

这两个答案: stackoverflow.com/a/3772911/17305  stackoverflow.com/a/5638187/17305 如果您想避免外部依赖,可能是已接受答案的替代方案。他们搬家了 gsub 打补丁看不见了 String,让这里的字符串更具可读性。 - Synoli


答案:


就我个人而言,我认为Ruby的缩进heredocs是无用的,它们应该更像Bash缩进的heredocs并且还可以删除空格  字符串......

无论如何,有几个图书馆试图处理这种情况。有很多库试图解决这个问题:


7
2017-07-28 08:15





如果您正在构建Rails应用程序,请尝试使用 strip_heredoc如果不是,您可以始终要求active_support核心扩展。

您的示例可能如下所示:

require 'active_support/core_ext'

class TestHelloWorld < Test::Unit::TestCase
  def test_hello
    assert_equal <<-EOS.strip_heredoc, hello_world
      Hello, world!
        World greets you
    EOS
  end
end

如果您确实不想包含它们,则会从active_support复制以下代码,以及如何处理格式设置的示例。

class String
  def try(*a, &b)
    if a.empty? && block_given?
      yield self
    else
      __send__(*a, &b)
    end
  end

  def strip_heredoc
    indent = scan(/^[ \t]*(?=\S)/).min.try(:size) || 0
    gsub(/^[ \t]{#{indent}}/, '')
  end
end

9
2018-04-22 15:15





我不确定这些可以被称为“最佳实践”,但这里有四种可能性

class Hello

  def self.world
"Hello, world!
  World greets you
"
  end
end

require 'test/unit'

class TestHelloWorld < Test::Unit::TestCase

#Define a constant array of multiline strings and test against the array
# see test_hello_4 
# Alternatively store the multi-line strings in a Yaml fixture file and load 
# them into a constant Hash or Array within a setup method
MLINE = [
"Hello, world!
  World greets you
",
"Another multi line string",
  ]

  # Create a method to return the string
  def test_hello_1
    assert_equal Hello.world, hello_world_string()
  end

  # Create the string using embedded newlines
  def test_hello_2
    assert_equal Hello.world, "Hello, world!\n  World greets you\n"
  end

  # if you only have 1 in the test then put it in a DATA section
  def test_hello_3
    assert_equal Hello.world, DATA.read
  end

  def test_hello_4
    assert_equal Hello.world, MLINE[0]
  end

  def hello_world_string
"Hello, world!
  World greets you
"
  end
end

__END__
Hello, world!
  World greets you

全部通过

Loaded suite test_hello_world
Started
....
Finished in 0.00083 seconds.

4 tests, 4 assertions, 0 failures, 0 errors

我个人更喜欢带嵌入换行符的字符串(方法2),除非字符串很长,在这种情况下我会选择DATA部分。


0
2017-07-28 07:45





它是关于格式化还是关于内容的测试?

如果它是关于格式化的测试,也许你的测试太高了,你应该测试一个“Formatter”类,你可能会找到一种方法来测试类,使得多行文本比较无用。然后,您将能够模拟Formatter类以检查它是否将接收所需的所有内容。例如,Formatter可以是具有a的类 add_line 在给出每个参数后添加“\ n”的方法和a formatted_string 这将返回多行字符串。一旦你测试了Formatter类,你就必须检查它是否被正确调用。这样,您就可以将内容测试与格式测试分开。

如果它是关于内容的测试,也许你应该按行拆分hello_world,然后检查第一行是否包含“Hello,world”,第二行包含“World greets you”。

我认为测试整个多行文本块并不是一个好习惯。


0
2017-07-28 08:10



一次性测试是唯一正确的方法。如果不同 - 测试应显示整个预期结果和整个实际结果。逐行比较,这样只是使测试失败报告毫无价值。 - taw
正如我在答案中所说,这实际上取决于您正在测试的内容:内容或格式?如果你真的想同时测试两者,我认为其他人已经给出了很好的答案。 - David