# If you run this from anything other than the main directory
# it will be unable to load the library or the fixtures.
# So... uh... don't.
require 'test/unit'
require 'lib/responsible_markup'
require 'digest/md5'
class ResponsibleMarkupTest < Test::Unit::TestCase
include ResponsibleMarkup
# Utility classes and functions
class MockTestResponse
attr_accessor :body
attr_accessor :headers
end
# Raise your hand if you want to type all that. Now put down your hand.
alias :l :lambda
alias :assert_passes :assert_nothing_raised
def setup
@fixtures = Hash.new
Dir.glob(File.join('test','fixtures','*.txt')) do |filename|
@fixtures[File.basename(filename, '.txt').to_sym] = File.open(filename, 'r') { |f| f.read }
end
@response = MockTestResponse.new
end
def teardown
ResponsibleMarkup::clear_cache
end
def load_fixture_to_response(fixture, headers = {})
@response.body = @fixtures[fixture]
@response.headers = headers
puts "Warning: fixtures/#{fixture}.txt does not exist." unless @response.body
end
def assert_fails(&block)
assert_raise Test::Unit::AssertionFailedError do
block.call
end
end
def assert_fails_with(message, &block)
begin
block.call
rescue Test::Unit::AssertionFailedError => e
# compare without whitespace since whitespace is for sissies
assert_equal(message.gsub(/[\s]/,''), e.message.gsub(/[\s]/,''), 'Assertion failed with an unexpected message')
else
assert_block('Assertion did not fail'){ false }
end
end
def assert_breaks(pr = nil)
begin
if pr
pr.call
else
yield
end
rescue
assert_block('Method broke'){ true }
else
assert_block('Method did not break'){ false }
end
end
def assert_all_fail(*args)
for i in 0..args.size-1
assert_fails{ args[i].call }
end
end
def assert_all_break(*args)
for i in 0..args.size-1
assert_breaks(args[i])
end
end
def assert_all_pass(*args)
for i in 0..args.size-1
assert_passes do
args[i].call
end
end
end
# Tests <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
def test_assert_compatible_empty_elements
# the good
load_fixture_to_response(:good_empty_elements)
assert_all_pass(
l{ assert_compatible_empty_elements },
l{ assert_compatible_empty_elements @response },
l{ assert_compatible_empty_elements @response, 'message' },
l{ assert_compatible_empty_elements @fixtures[:good_empty_elements] },
l{ assert_compatible_empty_elements @fixtures[:good_empty_elements], 'message' }
)
# the bad
load_fixture_to_response(:bad_empty_elements)
assert_all_fail(
l{ assert_compatible_empty_elements },
l{ assert_compatible_empty_elements @response },
l{ assert_compatible_empty_elements @response, 'message' },
l{ assert_compatible_empty_elements @fixtures[:bad_empty_elements] },
l{ assert_compatible_empty_elements @fixtures[:bad_empty_elements], 'message' }
)
# the neurotic
load_fixture_to_response(:bad_empty_elements)
assert_fails_with("Output has empty elements which may be incompatible with older browsers.\n Line 67, Column 32:\n
\n\n Line 89, Column 19:\n
\n\n Line 90, Column 4:\n
\n\n Line 92, Column 5:\n
\n\n Line 92, Column 23:\n
\n") do
assert_compatible_empty_elements
end
assert_fails_with("Sweet lord, it's got horrible empty elements!\n Line 67, Column 32:\n
\n\n Line 89, Column 19:\n
\n\n Line 90, Column 4:\n
\n\n Line 92, Column 5:\n
\n\n Line 92, Column 23:\n
\n") do
assert_compatible_empty_elements @response, "Sweet lord, it's got horrible empty elements!"
end
end
def test_assert_content_type
# the good
load_fixture_to_response(:valid_xhtml_10_strict, { 'Content-Type' => 'text/html; charset=iso-8859-1' })
assert_all_pass(
l{ assert_content_type(:charset => 'ISO-8859-1', :mime_type => 'text/html') },
l{ assert_content_type(:charset => 'ISO-8859-1') },
l{ assert_content_type(:content_type => 'text/html; charset=iso-8859-1') },
l{ assert_content_type(:content_type => 'text/html; charset=iso-8859-1') },
l{ assert_content_type(:content_type => {:charset => 'ISO-8859-1', :mime_type => 'text/html'}) },
l{ assert_content_type(:content => @fixtures[:valid_xhtml_10_strict], :charset => 'iso-8859-1') }
)
load_fixture_to_response(:valid_xhtml_10_strict)
assert_all_pass(
l{ assert_content_type(:charset => 'ISO-8859-1', :mime_type => 'text/html') },
l{ assert_content_type(:charset => 'ISO-8859-1') },
l{ assert_content_type(:content_type => 'text/html; charset=iso-8859-1') },
l{ assert_content_type(:content_type => 'text/html; charset=iso-8859-1') },
l{ assert_content_type(:content_type => {:charset => 'ISO-8859-1', :mime_type => 'text/html'}) },
l{ assert_content_type(:content => @fixtures[:valid_xhtml_10_strict], :charset => 'iso-8859-1') }
)
# the bad
# meta/header mismatch
load_fixture_to_response(:valid_xhtml_10_strict, { 'Content-Type' => 'text/html; charset=utf-8' })
assert_all_fail(
l{ assert_content_type(:charset => 'ISO-8859-1', :mime_type => 'text/html') },
l{ assert_content_type(:charset => 'ISO-8859-1') },
l{ assert_content_type(:content_type => 'text/html; charset=iso-8859-1') },
l{ assert_content_type(:content_type => {:charset => 'ISO-8859-1', :mime_type => 'text/html'}) }
)
# meta charset mismatch
load_fixture_to_response(:valid_xhtml_10_strict, { 'Content-Type' => 'text/html; charset=iso-8859-1' })
assert_all_fail(
l{ assert_content_type(:charset => 'ISO-8859-1', :mime_type => 'application/xml+xhtml') },
l{ assert_content_type(:content_type => 'application/xml+xhtm; charset=iso-8859-1') },
l{ assert_content_type(:content_type => {:charset => 'ISO-8859-1', :mime_type => 'application/xml+xhtm'}) }
)
# TODO: the neurotic
load_fixture_to_response(:valid_xhtml_10_strict, { 'Content-Type' => 'text/html; charset=iso-8859-1' })
assert_fails_with("Output content type did not match the expected content type.\nExpected content type was <\"text/html; charset=utf-8\"> but http-equiv content type was <\"text/html; charset=iso-8859-1\">.") do
assert_content_type
end
assert_fails_with("Crap crap crap.\nExpected content type was <\"text/html; charset=utf-8\"> but http-equiv content type was <\"text/html; charset=iso-8859-1\">.") do
assert_content_type({}, "Crap crap crap")
end
load_fixture_to_response(:valid_xhtml_10_strict, { 'Content-Type' => 'text/html; charset=utf-8' })
assert_fails_with("Output content type did not match the expected content type.\nExpected content type was <\"text/html; charset=utf-8\"> but http-equiv content type was <\"text/html; charset=iso-8859-1\">.") do
assert_content_type
end
load_fixture_to_response(:valid_xhtml_10_strict, { 'Content-Type' => 'text/html; charset=utf-8' })
assert_fails_with("Crap crap crap.\nExpected content type was <\"text/html; charset=utf-8\"> but http-equiv content type was <\"text/html; charset=iso-8859-1\">.") do
assert_content_type({}, 'Crap crap crap')
end
# TODO: the ugly
assert_all_break(
l{ assert_content_type :content => nil },
l{ assert_content_type :content_type => nil },
l{ assert_content_type :content_type => {} }
)
end
def test_assert_doctype
# the good
ResponsibleMarkup::DEFAULT_DOCTYPES.each do |doctype, value|
load_fixture_to_response("valid_#{doctype}".to_sym)
assert_all_pass(
l{ assert_doctype },
l{ assert_doctype :any },
l{ assert_doctype doctype },
l{ assert_doctype ['moo', :any] },
l{ assert_doctype [:any, 'moo'] },
l{ assert_doctype ['moo', doctype] },
l{ assert_doctype [doctype, 'moo'] },
l{ assert_doctype @fixtures["valid_#{doctype}".to_sym] },
l{ assert_doctype :content => @fixtures["valid_#{doctype}".to_sym], :doctype => doctype }
)
end
# the bad
load_fixture_to_response(:no_doctype)
assert_all_fail(
l{ assert_doctype },
l{ assert_doctype :any },
l{ assert_doctype :xhtml_11 },
l{ assert_doctype ['moo', :any] },
l{ assert_doctype [:any, 'moo'] },
l{ assert_doctype ['moo', :xhtml_11] },
l{ assert_doctype [:xhtml_11, 'moo'] },
l{ assert_doctype @response.body },
l{ assert_doctype :content => @response.body, :doctype => :xhtml_11 },
l{ assert_doctype :content => @fixtures[:valid_html_401_strict], :doctype => :xhtml_11 }
)
load_fixture_to_response(:custom_doctype)
assert_passes{ assert_doctype :doctype => '' }
# the neurotic
load_fixture_to_response(:no_doctype)
assert_fails_with("Output doctype does not match expected value(s).\nAny doctype expected but none found.") do
assert_doctype :any
end
assert_fails_with("mooo.\nAny doctype expected but none found.") do
assert_doctype :any, "mooo"
end
load_fixture_to_response(:valid_xhtml_11)
assert_fails_with("Outputdoctypedoesnotmatchexpectedvalue(s).<\"\">expectedbutwas<\"\">.") do
assert_doctype :xhtml_10_strict
end
assert_fails_with("mooo.<\"\">expectedbutwas<\"\">.") do
assert_doctype :xhtml_10_strict, "mooo"
end
# the ugly
load_fixture_to_response(:valid_xhtml_11)
assert_all_break(
l{ assert_doctype :something_i_can_never_have },
l{ assert_doctype 300 }
)
end
def test_assert_has_xml_prolog
# the good
load_fixture_to_response(:xml_with_prolog)
assert_all_pass(
l{ assert_has_xml_prolog },
l{ assert_has_xml_prolog @fixtures[:xml_with_prolog] },
l{ assert_has_xml_prolog :content => @fixtures[:xml_with_prolog] }
)
# the bad
load_fixture_to_response(:xml_without_prolog)
assert_all_fail(
l{ assert_has_xml_prolog },
l{ assert_has_xml_prolog @fixtures[:xml_without_prolog] },
l{ assert_has_xml_prolog :content => @fixtures[:xml_without_prolog] }
)
# the neurotic
load_fixture_to_response(:xml_without_prolog)
assert_fails_with("Output has no XML prolog.") do
assert_has_xml_prolog
end
assert_fails_with("Crappity crap crap.") do
assert_has_xml_prolog @response, 'Crappity crap crap'
end
# the ugly
load_fixture_to_response(:xml_without_prolog)
assert_all_break(
l{ assert_has_xml_prolog :moo },
l{ assert_has_xml_prolog nil },
l{ assert_has_xml_prolog :content => nil }
)
end
def test_assert_no_empty_attributes
# the good
load_fixture_to_response(:has_no_empty_attributes)
assert_all_pass(
l{ assert_no_empty_attributes },
l{ assert_no_empty_attributes @response },
l{ assert_no_empty_attributes @response, 'message' },
l{ assert_no_empty_attributes @fixtures[:has_no_empty_attributes] },
l{ assert_no_empty_attributes @fixtures[:has_no_empty_attributes], 'message' }
)
# the bad
load_fixture_to_response(:has_empty_attributes)
assert_all_fail(
l{ assert_no_empty_attributes },
l{ assert_no_empty_attributes @response },
l{ assert_no_empty_attributes @response, 'message' },
l{ assert_no_empty_attributes @fixtures[:has_empty_attributes] },
l{ assert_no_empty_attributes @fixtures[:has_empty_attributes], 'message' }
)
# the neurotic
load_fixture_to_response(:has_empty_attributes)
assert_fails_with("Output has empty attributes.\n Line 52, Column 14:\n