You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

70 lines
2.2 KiB

require 'launchy'
require 'erb'
require 'cairo'
require 'ruby-progressbar'
# An pixel-by-pixel comparison of sample images for visual regression testing
class Sanity
@@EXPECTED_DIR = "#{File.expand_path(File.dirname(__FILE__))}/expected/"
@@OUTPUT_DIR = "#{File.expand_path(File.dirname(__FILE__))}/../../samples/_output/"
@@DIFF_DIR = "#{File.expand_path(File.dirname(__FILE__))}/_diffs/"
@@SANITY_ERB = "#{File.expand_path(File.dirname(__FILE__))}/sanity.html.erb"
@@SANITY_HTML = "#{File.expand_path(File.dirname(__FILE__))}/sanity.html"
def images
images = []
exp_pngs = Dir[@@EXPECTED_DIR + "/**/*.png"]
bar = ProgressBar.create(title: 'Diffing images', total: exp_pngs.size)
exp_pngs.each do |exp_png|
row = []
actual_png = @@OUTPUT_DIR + File.basename(exp_png)
row << "file:///" + exp_png
row << "file:///" + actual_png # actual
row << "file:///" + diff_image(exp_png, actual_png)
images << row
bar.increment
end
bar.finish
return images
end
def run
puts "Building sanity test..."
sanity_template = File.read(@@SANITY_ERB)
process_erb(sanity_template)
Launchy.open("file:///" + @@SANITY_HTML)
puts "Done."
end
private
def diff_image(exp_file, actual_file)
exp = Cairo::ImageSurface.from_png(exp_file)
exp_data = exp.data.bytes
actual_data = Cairo::ImageSurface.from_png(actual_file).data.bytes
new_data = Array.new(exp_data.size, 255)
unless exp_data == actual_data # this seems to be the fastest initial comparison
(0..exp_data.size).each do |i|
empty = (i % 4 == 3) ? 0 : 255 # alpha channel is empty, others are just black
new_data[i] = (exp_data[i] == actual_data[i]) ? empty : 128
end
end
out = Cairo::ImageSurface.new(new_data.pack('c*'), exp.format, exp.width, exp.height, exp.stride)
out_file = @@DIFF_DIR + exp_file[exp_file.rindex("/")..-1]
out.write_to_png(out_file)
out_file
end
def diff_pixel(exp, actual)
(exp == actual) ? [0, 0, 0, 0] : [255, 0, 0, 255]
end
def process_erb(sanity_template)
renderer = ERB.new(sanity_template)
File.open(@@SANITY_HTML, 'w+') do |html|
html.write(renderer.result(binding))
end
end
end