#!/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("
#{md_pl}
",{ :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
(.*)
\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