5 class WrongColor < Exception
6 def initialize(pixel, is_color, desired_color)
9 @desired_color = desired_color
12 "Wrong color at %s (is: %06x should be: %06x)" % [@pixel.to_s, @is_color, @desired_color]
15 class AreaError < Exception
16 def initialize(area,problem)
17 @area,@problem = area,problem
20 "Area at #{@area} #{@problem}"
23 class PixelError < Exception
24 def initialize(p1, relation,p2)
25 @p1,@p2,@relation = p1,p2,relation
28 "Pixel #{@p1} #{@relation} #{@p2}"
31 class ConversionFailed < Exception
32 def initialize(output,file)
35 @exists = File.exists?(file)
38 puts "-"*26+" Conversion failed "+"-"*27
39 (puts @output) if @output
40 puts "file #{@file} doesn't exist" if not @exists
46 def initialize(x1,y1,x2,y2,file)
47 @x1,@y1,@x2,@y2,@file = x1,y1,x2,y2,file
49 def should_be_plain_colored
50 @rgb = @file.get_area(@x1,@y1,@x2,@y2) unless @rgb
51 @rgb.min == @rgb.max or raise AreaError.new(self,"is not plain colored: colors go from %06x to %06x" % [rgb_to_int(@rgb.min), rgb_to_int(@rgb.max)])
53 def should_not_be_plain_colored
54 @rgb = @file.get_area(@x1,@y1,@x2,@y2) unless @rgb
55 @rgb.min != @rgb.max or raise AreaError.new(self,"is plain colored")
57 def should_contain_text(text)
58 text2 = @file.get_text(@x1,@y1,@x2,@y2)
59 text2 == text or raise AreaError.new(self, "doesn't contain text \"#{text}\" (found: \"#{text2}\")")
61 def should_contain_link(url)
62 links = @file.get_links(@x1,@y1,@x2,@y2)
63 (links & [url]).empty? and raise AreaError.new(self, "doesn't contain url \"#{url}\"")
66 "(#{@x1},#{@y1},#{@x2},#{@y2})"
71 # ImageMagick rgb triples are 16 bit
72 (rgb.reverse+[0]).map {|c| c>>8}.pack("CCCC").unpack("i")[0]
77 def initialize(x,y,rgb)
80 def should_be_of_color(color2)
81 color1 = rgb_to_int(@rgb)
82 color1 == color2 or raise WrongColor.new(self, color1, color2)
84 def should_be_brighter_than(pixel)
85 gray1 = @rgb.inject(0) {|sum,e| sum+e}
86 gray2 = pixel.rgb.inject(0) {|sum,e| sum+e}
87 gray1 > gray2 or raise PixelError.new(self,"is not brighter than",pixel)
89 def should_be_darker_than(pixel)
90 gray1 = @rgb.inject(0) {|sum,e| sum+e}
91 gray2 = pixel.rgb.inject(0) {|sum,e| sum+e}
92 gray1 < gray2 or raise PixelError.new(self,"is not less bright than",pixel)
94 def should_be_the_same_as(pixel)
95 @rgb == pixel.rgb or raise PixelError.new(self,"is not the same as",pixel)
104 $tempfiles.each do |file|
110 def initialize(filename, page)
116 @swfname = @filename.gsub(/.pdf$/i,"")+".swf"
117 $tempfiles += [@swfname]
118 `pdfinfo #{@filename}` =~ /Page size:\s*([0-9]+) x ([0-9]+) pts/
120 dpi = (72.0 * 612 / width.to_i).to_i
121 output = `pdf2swf -f -s poly2bitmap -s zoom=#{dpi} -p #{@page} #{@filename} -o #{@swfname} 2>&1`
122 #output = `pdf2swf -s zoom=#{dpi} --flatten -p #{@page} #{@filename} -o #{@swfname} 2>&1`
123 raise ConversionFailed.new(output,@swfname) unless File.exists?(@swfname)
128 @pngname = @filename.gsub(/.pdf$/i,"")+".png"
130 output = `swfrender #{@swfname} -o #{@pngname} 2>&1`
131 raise ConversionFailed.new(output,@pngname) unless File.exists?(@pngname)
132 @img = Magick::Image.read(@pngname).first
137 def get_text(x1,y1,x2,y2)
139 #puts "swfstrings -x #{x1} -y #{y1} -W #{x2-x1} -H #{y2-y1} #{@swfname}"
140 #puts `swfstrings -x #{x1} -y #{y1} -W #{x2-x1} -H #{y2-y1} #{@swfname}`
141 `swfstrings -x #{x1} -y #{y1} -W #{x2-x1} -H #{y2-y1} #{@swfname}`.chomp
143 def get_links(x1,y1,x2,y2)
145 t = `swfdump -a #{@swfname}`
146 links = t.scan(/GetUrl2? URL:"([^"]*)"/).inject([]) do |a,u| a + u end
147 t.scan(/name "url:([^"]*)"/).inject(links) do |a,u| a + u end
149 def get_area(x1,y1,x2,y2)
151 data = @img.export_pixels(x1, y1, x2-x1, y2-y1, "RGB")
152 Array.new(data.size/3) { |i| data.slice(i*3,3) }
154 def area_at(x1,y1,x2,y2)
155 return Area.new(x1,y1,x2,y2,self)
167 data = @img.export_pixels(x, y, 1, 1, "RGB")
168 return Pixel.new(x,y,data)
172 module Spec::Example::ExampleGroupMethods
173 alias :convert_file :example
176 class FileExampleGroup < Spec::Example::ExampleGroup
177 def area_at(x1,y1,x2,y2)
178 @file.area_at(x1,y1,x2,y2)
191 Spec::Example::ExampleGroupFactory.default(FileExampleGroup)
193 Spec::Runner.configure do |config|
195 input_file = File.join(File.dirname(__FILE__), description)
196 raise "Cannot find input file #{input_file}" unless File.exists?(input_file)
197 @file = DocFile.new(input_file, 1)