Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby indented multiline strings [duplicate]

It's a best-practice question. There are obvious ways to do that, none of them just seem quite right.

Quite often I need to test that some multi-line string gets produced. This normally breaks indentation making everything look like a mess:

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

With <<- I can indent here doc marker, but it doesn't strip indentation inside heredoc, it still looks horrible.

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

This lets me indent but readability of test line suffers. This gsub really doesn't feel right here.

class TestHelloWorld < Test::Unit::TestCase
  def test_hello
    assert_equal <<-EOS.gsub(/^ {6}/, ""), hello_world
      Hello, world!
        World greets you
    EOS
  end
end

Is there any way to test such multi-line strings that's really readable?

like image 650
taw Avatar asked Jul 28 '10 07:07

taw


People also ask

How do you create a multiline string in Ruby?

The easiest way to create a multiline string is to just use multiple lines between quotation marks: address = "Four score and seven years ago our fathers brought forth on this continent, a new nation, conceived in Liberty, and dedicated to the proposition that all men are created equal."

What is %{} in ruby?

This is percent sign notation. The percent sign indicates that the next character is a literal delimiter, and you can use any (non alphanumeric) one you want. For example: %{stuff} %[stuff] %?

What is EOS in Ruby?

EOS means end of string. it is displayed at the end of the string.


1 Answers

If you're building a Rails application, try using strip_heredoc, if not you could always require active_support core extensions.

Your Example might look like this:

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

If you really don't want to include them, the following code is copied from active_support as and example of how you might handle the formatting.

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
like image 70
Leo O'Donnell Avatar answered Sep 29 '22 05:09

Leo O'Donnell