38ae064b8a
Sam Ruby has been doing a bang-up job fixing the bugs in REXML. Who knows when these improvements will trickle down to vendor distributions of Ruby. In the meantime, let's bundle the latest version of REXML with Instiki. We check the version number of the bundled REXML against that of the System REXML, and use whichever is later.
350 lines
6.6 KiB
Ruby
350 lines
6.6 KiB
Ruby
#!/usr/bin/env ruby
|
|
|
|
require 'maruku'
|
|
#require 'maruku/textile2'
|
|
require 'maruku/input_textile2/t2_parser'
|
|
|
|
$marutest_language = :markdown
|
|
|
|
#MARKER = "\n***EOF***\n"
|
|
SPLIT = %r{\n\*\*\*[^\*]+\*\*\*\n}m
|
|
|
|
def marker(x)
|
|
"\n*** Output of #{x} ***\n"
|
|
end
|
|
|
|
def write_lines(i, j, lines, prefix, i_star)
|
|
i = [i, 0].max
|
|
j = [j, lines.size-1].min
|
|
for a in i..j
|
|
l = lines[a].gsub(/\t/,' ')
|
|
puts( ("%s %3d" % [prefix, a]) +
|
|
(a==i_star ? " -->" : " ")+lines[a])
|
|
end
|
|
end
|
|
|
|
# a = expected b = found
|
|
def equals(a, b)
|
|
a = a.split("\n")
|
|
b = b.split("\n")
|
|
|
|
for i in 0..([a.size-1,b.size-1].max)
|
|
la = a[i]
|
|
lb = b[i]
|
|
if la != lb
|
|
puts "\n"
|
|
|
|
|
|
write_lines(i-3, i+3, a, "expected", i )
|
|
write_lines(i-3, i+3, b, " found", i )
|
|
return false
|
|
end
|
|
end
|
|
return true
|
|
end
|
|
|
|
TOTEST = [:inspect,:to_html,:to_latex,:to_md,:to_s]
|
|
|
|
def run_test(filename, its_ok, verbose=true)
|
|
# read file content
|
|
input = (f=File.open(filename,'r')).read; f.close
|
|
|
|
output_html = File.join(File.dirname(filename),
|
|
File.basename(filename, File.extname(filename)) + ".html")
|
|
|
|
# split the input in sections
|
|
|
|
stuff = input.split(SPLIT)
|
|
if stuff.size == 1
|
|
stuff[2] = stuff[0]
|
|
stuff[0] = "Write a comment here"
|
|
stuff[1] = "{} # params "
|
|
end
|
|
|
|
comment = stuff.shift
|
|
params_s = stuff.shift
|
|
|
|
params = eval(params_s||'{}')
|
|
if params == nil
|
|
raise "Null params? #{params_s.inspect}"
|
|
end
|
|
|
|
markdown = stuff.shift
|
|
|
|
# puts "comment: #{markdown.inspect}"
|
|
# puts "markdown: #{markdown.inspect}"
|
|
|
|
failed = []
|
|
relaxed = []
|
|
crashed = []
|
|
actual = {}
|
|
|
|
doc =
|
|
if $marutest_language == :markdown
|
|
Maruku.new(markdown, params)
|
|
else
|
|
MaRuKu.textile2(markdown, params)
|
|
end
|
|
|
|
for s in TOTEST
|
|
begin
|
|
if s==:to_html
|
|
actual[s] = doc.to_html
|
|
else
|
|
actual[s] = doc.send s
|
|
raise "Methods #{s} gave nil" if not actual[s]
|
|
end
|
|
rescue Exception => e
|
|
crashed << s
|
|
actual[s] = e.inspect+ "\n"+ e.backtrace.join("\n")
|
|
puts actual[s]
|
|
end
|
|
end
|
|
|
|
File.open(output_html, 'w') do |f|
|
|
f.write doc.to_html_document
|
|
end
|
|
|
|
begin
|
|
m = Maruku.new
|
|
d = m.instance_eval(actual[:inspect])
|
|
rescue Exception => e
|
|
s = e.inspect + e.backtrace.join("\n")
|
|
raise "Inspect is not correct:\n ========\n#{actual[:inspect]}"+
|
|
"============\n #{s}"
|
|
end
|
|
|
|
expected = {}
|
|
if (stuff.size < TOTEST.size)
|
|
$stdout.write " (first time!) "
|
|
TOTEST.each do |x| expected[x] = actual[x] end
|
|
else
|
|
TOTEST.each_index do |i|
|
|
symbol = TOTEST[i]
|
|
expected[symbol] = stuff[i]
|
|
# puts "symbol: #{symbol.inspect} = #{stuff[i].inspect}"
|
|
end
|
|
end
|
|
|
|
m = Maruku.new
|
|
|
|
|
|
if not its_ok.include? :inspect
|
|
begin
|
|
d = m.instance_eval(expected[:inspect])
|
|
# puts "Eval: #{d.inspect}"
|
|
expected[:inspect] = d.inspect
|
|
rescue Exception => e
|
|
s = e.inspect + e.backtrace.join("\n")
|
|
raise "Cannot eval user-provided string:\n #{expected[:inspect].to_s}"+
|
|
"\n #{s}"
|
|
end
|
|
end
|
|
|
|
# m.instance_eval(actual[:inspect]) != m.instance_eval(expected[:inspect])
|
|
|
|
# actual[:inspect] = m.instance_eval(actual[:inspect])
|
|
# expected[:inspect] = m.instance_eval(expected[:inspect])
|
|
|
|
|
|
TOTEST.each do |x|
|
|
expected[x].strip!
|
|
actual[x].strip!
|
|
if not equals(expected[x], actual[x])
|
|
if its_ok.include? x
|
|
expected[x] = actual[x]
|
|
$stdout.write " relax:#{x} "
|
|
relaxed << x
|
|
else
|
|
actual[x] = "-----| WARNING | -----\n" + actual[x].to_s
|
|
failed << x
|
|
end
|
|
end
|
|
end
|
|
|
|
f = File.open(filename, 'w')
|
|
|
|
f.write comment
|
|
f.write "\n*** Parameters: ***\n"
|
|
f.write params_s
|
|
f.write "\n*** Markdown input: ***\n"
|
|
f.write markdown
|
|
|
|
TOTEST.each do |x|
|
|
f.write marker(x)
|
|
f.write expected[x]
|
|
end
|
|
f.write "\n*** EOF ***\n"
|
|
|
|
if not failed.empty? or not crashed.empty?
|
|
|
|
f.puts "\n\n\n\nFailed tests: #{failed.inspect} \n"
|
|
|
|
TOTEST.each do |x|
|
|
f.write marker(x)
|
|
f.write actual[x]
|
|
end
|
|
|
|
else
|
|
f.puts "\n\n\n\tOK!\n\n\n"
|
|
end
|
|
|
|
|
|
md_pl = markdown_pl(markdown)
|
|
|
|
f.write "\n*** Output of Markdown.pl ***\n"
|
|
f.write md_pl
|
|
|
|
f.write "\n*** Output of Markdown.pl (parsed) ***\n"
|
|
begin
|
|
doc = REXML::Document.new("<div>#{md_pl}</div>",{
|
|
:compress_whitespace=>['div','p'],
|
|
:ignore_whitespace_nodes=>['div','p'],
|
|
:respect_whitespace=>['pre','code']
|
|
})
|
|
div = doc.root
|
|
xml =""
|
|
indent=1
|
|
if $rexml_new_version
|
|
formatter = if indent > -1
|
|
REXML::Formatters::Pretty.new( indent, ie_hack=false )
|
|
else
|
|
REXML::Formatters::Default.new( ie_hack=false )
|
|
end
|
|
formatter.write( div, xml)
|
|
else
|
|
div.write(xml,indent,transitive=true,ie_hack=false)
|
|
end
|
|
xml.gsub!("\A<div>(.*)</div>\Z", "\1")
|
|
f.write xml
|
|
rescue Exception=>e
|
|
f.puts "Error: #{e.inspect}"
|
|
end
|
|
f.close
|
|
|
|
|
|
return failed, relaxed, crashed
|
|
end
|
|
|
|
def markdown_pl(markdown)
|
|
tmp1 = "/tmp/marutest1"
|
|
tmp2 = "/tmp/marutest2"
|
|
File.open(tmp1,'w') do |f| f.puts markdown end
|
|
system "bin/Markdown.pl < #{tmp1} > #{tmp2}"
|
|
f = File.open(tmp2,'r')
|
|
s = f.read
|
|
f.close
|
|
s
|
|
end
|
|
|
|
def passed?(args, arg)
|
|
if args.include? arg
|
|
args.delete arg
|
|
true
|
|
else
|
|
false
|
|
end
|
|
end
|
|
|
|
def marutest(args)
|
|
dont_worry = []
|
|
TOTEST.each do |x|
|
|
arg = "ok:#{x}"
|
|
# puts arg
|
|
if passed?(args, arg)
|
|
dont_worry << x
|
|
end
|
|
end
|
|
|
|
if passed?(args, 'ok')
|
|
dont_worry = TOTEST.clone
|
|
end
|
|
|
|
if dont_worry.size > 0
|
|
puts "Relaxed on #{dont_worry.inspect}"
|
|
end
|
|
|
|
|
|
failed = {}
|
|
relaxed = {}
|
|
|
|
args.each do |f|
|
|
$stdout.write f + ' '*(50-f.size) + " "
|
|
$stdout.flush
|
|
tf, tr, tcrashed = run_test(f, dont_worry)
|
|
|
|
tf = tf + tcrashed
|
|
|
|
|
|
if tr.size > 0
|
|
$stdout.write " relax #{tr.inspect} "
|
|
end
|
|
|
|
if tf.size>0
|
|
$stdout.write " failed on #{tf.inspect} "
|
|
else
|
|
$stdout.write " OK "
|
|
end
|
|
|
|
if tcrashed.size > 0
|
|
$stdout.write " CRASHED on #{tcrashed.inspect}"
|
|
end
|
|
|
|
$stdout.write "\n"
|
|
|
|
failed[f] = tf
|
|
relaxed[f] = tr
|
|
end
|
|
|
|
num_failed = 0
|
|
failed_cat = {}
|
|
|
|
puts "\n\n\n**** FINAL REPORT ****\n\n"
|
|
|
|
|
|
if failed.size > 0
|
|
failed.each do |file, fl|
|
|
num_failed += fl.size
|
|
if fl.size > 0
|
|
puts "\t#{file}\tfailed on #{fl.inspect}"
|
|
end
|
|
fl.each do |x|
|
|
failed_cat[x] = failed_cat[x] || 0
|
|
failed_cat[x] = failed_cat[x] + 1
|
|
end
|
|
end
|
|
end
|
|
|
|
if dont_worry.size > 0
|
|
puts "Relaxed on #{dont_worry.inspect}"
|
|
end
|
|
|
|
if relaxed.size > 0
|
|
relaxed.each do |file, r|
|
|
if r.size > 0
|
|
puts "\t#{file}\t\trelaxed on #{r.inspect}"
|
|
end
|
|
end
|
|
end
|
|
|
|
if failed_cat.size > 0
|
|
puts "\nCategories:\n"
|
|
|
|
failed_cat.each do |x, num|
|
|
puts "\t#{x.inspect} \tfailed #{num}/#{args.size}"
|
|
end
|
|
end
|
|
|
|
return num_failed == 0
|
|
end
|
|
|
|
if File.basename(__FILE__) == 'marutest'
|
|
if ARGV.empty?
|
|
puts "marutest is a tool for running Maruku's unittest."
|
|
exit 1
|
|
end
|
|
ok = marutest(ARGV.clone)
|
|
|
|
exit ok ? 0 : -1
|
|
end
|
|
|