require 'spec_helper'
require 'dimensions'
# this file contains the time-consuming tests that shell out to phantomjs
def pdf_valid?(io)
# quick & dirty check
case io
when File
io.read[0...4] == "%PDF"
when String
io[0...4] == "%PDF" || File.open(io).read[0...4] == "%PDF"
end
end
def prepare_file outfile
# TODO: there MUST be a better way of handling file output in rspec
# (can't mock file ops because the output is coming from phantomjs)
File.delete(outfile) if File.exists?(outfile)
return '/tmp/' + outfile
end
describe Shrimple do
it "echoes its arguments" do
s = Shrimple.new(renderer: 'spec/parse_and_print_stdin.js')
output = s.render
result = JSON.parse(output.stdout)
expect(result['renderer']).to eq 'spec/parse_and_print_stdin.js'
expect(result['processed']).to eq true # added by the phantom script
expect(output.stderr).to eq ""
end
# well I give up. can't find an item settable by --config that I can read in js. :(
# https://github.com/ariya/phantomjs/issues/12265
#
# it "sets a command-line arg" do
# s = Shrimple.new
# s.config.loadImages = false
# s.config.autoLoadImages = false
# s.renderer = 'render_max_disk_cache.js'
# s.render
# end
it "renders text to a string" do
callback_param = nil
s = Shrimple.new
s.onSuccess = Proc.new do |result|
# make sure this process isn't removed from the process table
# until after this callback returns.
sleep(0.2)
expect(Shrimple.processes.count).to eq 1
callback_param = result
end
s.onError = Proc.new { fail }
result = s.render_text("file://#{example_html}")
output = result.stdout # TODO: get rid of this line
expect(output).to eq "Hello World!\n"
expect(callback_param).to eq result
end
it "renders text to a file" do
outfile = prepare_file('shrimple-test-output.txt')
s = Shrimple.new
s.render_text("file://#{example_html}", to: outfile)
output = File.read(outfile)
expect(output).to eq "Hello World!\n"
File.delete(outfile)
end
it "renders html to a string" do
s = Shrimple.new
result = s.render_html("file://#{example_html}")
output = result.stdout # TODO: get rid of this line
expect(output).to include "
Hello World!
"
end
it "handles a missing file" do
# also ensures failures's stderr appears in the exception
callback_param = nil
s = Shrimple.new
s.onSuccess = Proc.new { fail }
s.onError = Proc.new { |result| callback_param = result }
expect {
s.render_text("file://this-does-not-exist")
}.to raise_exception(Shrimple::PhantomError, /Unable to load.*this-does-not-exist/)
expect(callback_param).to be_a Shrimple::Phantom
end
it "handles a missing file in background mode" do
callback_param = nil
s = Shrimple.new(background: true)
s.onSuccess = Proc.new { fail }
s.onError = Proc.new { |result| callback_param = result }
result = s.render_text("file://this-does-not-exist")
child = Shrimple.processes.wait_next
expect(child).to eq result
expect(result.success?).to eq false
expect(result.stderr).to match(/Unable to load.*this-does-not-exist/)
expect(callback_param).to eq result
end
it "handles phantomjs complaining about a missing render script" do
s = Shrimple.new(renderer: 'this-does-not-exist')
expect {
s.render_text("file://#{example_html}")
}.to raise_exception(Shrimple::PhantomError, /Can't open 'this-does-not-exist'/)
end
it "handles phantomjs complaining about a missing render script in background mode" do
s = Shrimple.new(renderer: 'this-does-not-exist', background: true)
result = s.render_text("file://#{example_html}")
child = Shrimple.processes.wait_next
expect(child).to eq result
expect(result.success?).to eq false
expect(result.stderr).to match(/Can't open 'this-does-not-exist'/)
end
# # it's hopeless: https://github.com/ariya/phantomjs/issues/10687
#
# it "handles a syntax error in a render script" do
# s = Shrimple.new(renderer: 'spec/syntax_error.js')
# expect {
# s.render_text("file://#{example_html}")
# }.to raise_exception(/Can't open 'this-does-not-exist'/)
# end
it "supports a debugging mode" do
# isn't there a better way of resetting global variables in rspec?
olderr = $stderr
begin
$stderr = StringIO.new
s = Shrimple.new(debug: true)
s.render_text("file://#{example_html}")
expect($stderr.string).to match /^COMMAND: \[.*phantomjs.*render.js"\]/
expect($stderr.string).to match /^STDIN: {.*"debug":true.*}/
ensure
$stderr = olderr
end
end
it "renders a pdf to a file" do
outfile = prepare_file('shrimple-test-output.pdf')
s = Shrimple.new(to: outfile)
s.render_pdf "file://#{example_html}"
expect(File.exists? outfile).to eq true
expect(pdf_valid?(File.new(outfile))).to eq true
end
it "renders a png to a file" do
outfile = prepare_file('shrimple-test-output.png')
s = Shrimple.new
p = s.render_png "file://#{example_html}", output: outfile
expect(File.exists? outfile).to eq true
dimensions = Dimensions.dimensions(outfile)
expect(dimensions[0]).to eq 400 # phantomjs default width
expect(dimensions[1]).to eq 300 # phantomjs default height
# when dimensions allows reading the filetype, add that check here
# https://github.com/cleanio/dimensions/commit/c61ad05c354feb1063bfbdc97c1ec5456c9ad43a
end
it "renders a png to a stream" do
s = Shrimple.new(page: {viewportSize: { width: 555, height: 555 }} )
s.page.zoomFactor = 0.75
output = s.render_png "file://#{example_html}"
# todo: would be great if we could attach Dimensions straight to the io object reading the results
# instead of needing to flush the result to a memory buffer and wrapping that in a new stringio
dimensions = Dimensions(StringIO.new(output.stdout))
expect(dimensions.width).to eq 555
expect(dimensions.height).to eq 555
end
it "renders a jpeg to a file" do
outfile = prepare_file('shrimple-test-output.jpg')
s = Shrimple.new
s.page.viewportSize = { width: 320, height: 240 }
s.output = outfile
output = s.render_jpeg "file://#{example_html}"
expect(File.exists? outfile).to eq true
dimensions = Dimensions.dimensions(outfile)
expect(dimensions[0]).to eq 320
expect(dimensions[1]).to eq 240
end
it "renders a gif to memory" do
s = Shrimple.new
s.page.viewportSize = { width: 213, height: 214 }
output = s.render_gif "file://#{example_html}"
dimensions = Dimensions(StringIO.new(output.stdout))
expect(dimensions.width).to eq 213
expect(dimensions.height).to eq 214
end
end