Unit testing generated content

Hi,

I'm writing unit test.

I've programmed already an assert method, which purpose it to compare
a string or a file with unix diff.
The goal is to assert that a generated content multiline is exactly
what I expect.

All the beginning of the code is a kind of polymorphism, treating
argument as string or filename

All the assert job is really done in the 4 last line, with unix diff.

    def assert_content_equal(expected, actual, message = nil)
        # compare avec diff
        expected_f = "/tmp/expected#{$$}"
        actual_f = "/tmp/actual#{$$}"
        remove_expected_f = true
        remove_actual_f = true

        if expected.kind_of? String
            if (expected.size < 255 and FileTest.exists? expected)
                expected_f = expected
                remove_expected_f = false
            else
                # création du fichier avec le contenu de la string
expected
                File.open(expected_f, "w") { |f| f.print expected }
            end
        else
            raise "expected String ou nom de fichier"
        end

        # code idem avec s/expected/actual/g
        # besoin de matchit : ?if expected^MV%%"cy/# code idem^M2jV%
%x"cPV%%:s/expected/actual/g^M
        if actual.kind_of? String
            if (actual.size < 255 and FileTest.exists? actual)
                actual_f = actual
                remove_actual_f = false
            else
                # création du fichier avec le contenu de la string
actual
                File.open(actual_f, "w") { |f| f.print actual }
            end
        else
            raise "actual String ou nom de fichier"
        end

        diff = `diff #{expected_f} #{actual_f}`
        File.unlink(expected_f) if remove_expected_f
        File.unlink(actual_f) if remove_actual_f
        assert_block("échec diff <expected >actual\n#{diff}") { $? ==
0 }
    end

What I would like to do now, is to have a regexp assert multiline
match, some thing like :

assert_match_regexp(actual) {
/^start/
/something .*/
/^\s*$/
/^end/
}

Which mean I expect 4 lines, individually matching the associated
regexp

Do you see a want to achieve?

I mean, reading the blockgiven, counting the regexp, and asserting the
whole...

More that that a full regexpdiff in fact ! :wink:

Any link or clue/hint, would be nice.

Regards,
Sylvain.

sylvain wrote:

What I would like to do now, is to have a regexp assert multiline
match, some thing like :

assert_match_regexp(actual) {
/^start/
/something .*/
/^\s*$/
/^end/
}

Which mean I expect 4 lines, individually matching the associated
regexp

You can match a single regexp across a multi-line string; using /m
option is clearer since . then matches any character including newline.

str = "foo\nbar\nbaz\nbap\n"

=> "foo\nbar\nbaz\nbap\n"

str =~ /^bar$\n^baz$\n^bap$/m

=> 4

str =~ /^bar$.*^bap$/m

=> 4

···

--
Posted via http://www.ruby-forum.com/\.

sylvain wrote:

What I would like to do now, is to have a regexp assert multiline
match, some thing like :

assert_match_regexp(actual) {
/^start/
/something .*/
/^\s*$/
/^end/
}

Which mean I expect 4 lines, individually matching the associated
regexp

Do you see a want to achieve?

I mean, reading the blockgiven, counting the regexp, and asserting the
whole...

More that that a full regexpdiff in fact ! :wink:

Any link or clue/hint, would be nice.

How about:

def test_it(str)
  num_lines = 4
  regexs = [/^start/, /something .*/, /^\s*$/, /^end/]

  lines = str.split("\n")
  return false if lines.length != num_lines

  match_results = lines.zip(regexs).collect{|line, regex| line =~ regex}
  match_results.all?
end

s1 =<<ENDOFSTRING
start
something else

end of data
ENDOFSTRING

s2 =<<ENDOFSTRING
start
something else

end of data
too many lines
ENDOFSTRING

s3 =<<ENDOFSTRING
start
something else
no match here
end of data
ENDOFSTRING

[s1, s2, s3].each do |str|
  puts test_it(str)
end

--output:--
true
false
false

···

--
Posted via http://www.ruby-forum.com/\.

Hi,

Hey cool seems great.
I've tried to find a way of passing regexps through the block (Proc) without
success.

But by array it's fine too.

def test_it(str)

num_lines = 4
regexs = [/^start/, /something .*/, /^\s*$/, /^end/]

lines = str.split("\n")
return false if lines.length != num_lines

match_results = lines.zip(regexs).collect{|line, regex| line =~ regex}
match_results.all?
end

Thanks, I will post the final assert, when It will be ready.

Do you think I can group my own assertion in a module or something and load
it into my testcase ?
For the moment I've just added a method into the testcase, was used only
here.

Regards,
Sylvain Viart.