module HammerCLI module Testing module OutputMatchers class MatcherBase include Minitest::Assertions def initialize(expected="") @expected = expected end def assert_match(test_ctx, actual) test_ctx.assert_equal(@expected, actual) end end class FieldMatcher < MatcherBase def initialize(label, value) @expected = FieldMatcher.matcher(label, value) end def assert_match(test_ctx, actual) message = "Regex /#{@expected.source}/ didn't match the output:\n#{actual}" test_ctx.assert(@expected =~ actual, message) end def self.matcher(label, value) Regexp.new(Regexp.quote(label) + ':[ ]+' + Regexp.quote(value)) end end class OutputMatcher < MatcherBase attr_accessor :expected_lines def initialize(expected="", options={}) @expected_lines = expected.is_a?(Array) ? expected : [expected] @ignore_whitespace = options.fetch(:ignore_whitespace, true) end def assert_match(test_ctx, actual) if @ignore_whitespace expected_lines = strip_lines(@expected_lines) actual = strip_lines(actual.split("\n")).join("\n") else expected_lines = @expected_lines end expected_lines = expected_lines.join("\n") message = "Output didn't contain expected lines:\n" + diff(expected_lines, actual) test_ctx.assert(actual.include?(expected_lines), message) end protected def strip_lines(lines) lines.map(&:rstrip) end end class IndexMatcher < MatcherBase def initialize(expected=[]) @line_matchers = [] expected.each do |line_expectation| @line_matchers << IndexLineMatcher.new(line_expectation) end end def assert_match(test_ctx, actual) @line_matchers.each do |matcher| matcher.assert_match(test_ctx, actual) end end end class IndexLineMatcher < MatcherBase def initialize(expected=[]) @expected_values = expected end def assert_match(test_ctx, actual) message = [ "Regex didn't match the output.", "Expected regex:", line_regexp.source, "Expected fields:", @expected_values.join(' | '), "Actual output:", actual ].join("\n") test_ctx.assert(line_regexp =~ actual, message) end protected def line_regexp re = @expected_values.map do |column| Regexp.quote(column) end.join('[ ]*\|[ ]*') Regexp.new("[ ]*#{re}[ ]*") end end end end end