pax_global_header 0000666 0000000 0000000 00000000064 14021261703 0014506 g ustar 00root root 0000000 0000000 52 comment=d1b6679ca290dd7f3505dd254bc28ff7bbd2465c
ruby-prawn-svg-0.32.0/ 0000775 0000000 0000000 00000000000 14021261703 0014473 5 ustar 00root root 0000000 0000000 ruby-prawn-svg-0.32.0/.github/ 0000775 0000000 0000000 00000000000 14021261703 0016033 5 ustar 00root root 0000000 0000000 ruby-prawn-svg-0.32.0/.github/workflows/ 0000775 0000000 0000000 00000000000 14021261703 0020070 5 ustar 00root root 0000000 0000000 ruby-prawn-svg-0.32.0/.github/workflows/test.yml 0000664 0000000 0000000 00000000625 14021261703 0021575 0 ustar 00root root 0000000 0000000 name: test
on: [push, pull_request]
jobs:
rake:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
ruby: [2.3, 2.4, 2.5, 2.6, 2.7, '3.0']
steps:
- uses: actions/checkout@v2
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
bundler-cache: true
ruby-version: ${{ matrix.ruby }}
- name: Run tests
run: bundle exec rake
ruby-prawn-svg-0.32.0/.gitignore 0000664 0000000 0000000 00000000164 14021261703 0016464 0 ustar 00root root 0000000 0000000 .DS_Store
spec/sample_output/*.pdf
prawn-svg-*.gem
Gemfile.lock
.rvmrc
.*.swp
.ruby-version
vendor/bundle/
.bundle/
ruby-prawn-svg-0.32.0/.rspec 0000664 0000000 0000000 00000000037 14021261703 0015610 0 ustar 00root root 0000000 0000000 --format documentation
--color
ruby-prawn-svg-0.32.0/Gemfile 0000664 0000000 0000000 00000001063 14021261703 0015766 0 ustar 00root root 0000000 0000000 source "http://rubygems.org"
# Declare your gem's dependencies in prawn-svg.gemspec.
# Bundler will treat runtime dependencies like base dependencies, and
# development dependencies will be added by default to the :development group.
gemspec
# Declare any dependencies that are still in development here instead of in
# your gemspec. These might include edge Rails or gems from your path or
# Git. Remember to move these dependencies to your gemspec before releasing
# your gem to rubygems.org.
# To use debugger
# gem 'ruby-debug19', :require => 'ruby-debug'
ruby-prawn-svg-0.32.0/LICENSE 0000664 0000000 0000000 00000002063 14021261703 0015501 0 ustar 00root root 0000000 0000000 The MIT License
Copyright 2010-2019 Roger Nesbitt
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
ruby-prawn-svg-0.32.0/README.md 0000664 0000000 0000000 00000015236 14021261703 0015761 0 ustar 00root root 0000000 0000000 # prawn-svg
[](https://badge.fury.io/rb/prawn-svg)

An SVG renderer for the Prawn PDF library.
This will take an SVG document as input and render it into your PDF. Find out more about the Prawn PDF library at:
http://github.com/prawnpdf/prawn
prawn-svg is compatible with all versions of Prawn from 0.11.1 onwards, including the 1.x and 2.x series.
The minimum Ruby version required is 2.3.0.
## Using prawn-svg
```ruby
Prawn::Document.generate("test.pdf") do
svg ''
end
```
prawn-svg will do something sensible if you call it with only an SVG document, but you can also
pass the following options to tailor its operation:
Option | Data type | Description
----------- | --------- | -----------
:at | [integer, integer] | Specify the location on the page you want the SVG to appear.
:position | :left, :center, :right, integer | If :at not specified, specifies the horizontal position to show the SVG. Defaults to :left.
:vposition | :top, :center, :bottom, integer | If :at not specified, specifies the vertical position to show the SVG. Defaults to current cursor position.
:width | integer | Desired width of the SVG. Defaults to horizontal space available.
:height | integer | Desired height of the SVG. Defaults to vertical space available.
:enable_web_requests | boolean | If true, prawn-svg will make http and https requests to fetch images. Defaults to true.
:enable_file_requests_with_root | string | If not nil, prawn-svg will serve `file:` URLs from your local disk if the file is located under the specified directory. It is very dangerous to specify the root path ("/") if you're not fully in control of your input SVG. Defaults to `nil` (off).
:cache_images | boolean | If true, prawn-svg will cache the result of all URL requests. Defaults to false.
:fallback_font_name | string | A font name which will override the default fallback font of Times-Roman. If this value is set to nil, prawn-svg will ignore a request for an unknown font and log a warning.
## Examples
```ruby
# Render the logo contained in the file logo.svg at 100, 100 with a width of 300
svg IO.read("logo.svg"), at: [100, 100], width: 300
# Render the logo at the current Y cursor position, centered in the current bounding box
svg IO.read("logo.svg"), position: :center
# Render the logo at the current Y cursor position, and serve file: links relative to its directory
root_path = "/apps/myapp/current/images"
svg IO.read("#{root_path}/logo.svg"), enable_file_requests_with_root: root_path
```
## Supported features
prawn-svg supports most but not all of the full SVG 1.1 specification. It currently supports:
- <line>, <polyline>, <polygon>, <circle> and <ellipse>
- <rect>. Rounded rects are supported, but only one radius is applied to all corners.
- <path> supports all commands defined in SVG 1.1, although the
implementation of elliptical arc is a bit rough at the moment.
- ``, `` and `` with attributes `x`, `y`, `dx`, `dy`, `rotate`, 'textLength', 'lengthAdjust', and with extra properties
`text-anchor`, `text-decoration` (underline only), `font-size`, `font-family`, `font-weight`, `font-style`, `letter-spacing`
- <svg>, <g> and <symbol>
- <use>
- <style> (see CSS section below)
- <image> with http:, https:, data:image/\*;base64 and `file:` schemes
(`file:` is disabled by default for security reasons, see Options section above)
- <clipPath>
- ``
- `` and `` are implemented on Prawn 2.2.0+ with attributes `gradientUnits` and `gradientTransform` (spreadMethod and stop-opacity are unimplemented.)
- `` and ``, although prawn-svg cannot handle any data that is not SVG so ``
tags are always ignored.
- properties: `clip-path`, `color`, `display`, `fill`, `fill-opacity`, `fill-rule`, `opacity`, `overflow`, `stroke`, `stroke-dasharray`, `stroke-linecap`, `stroke-opacity`, `stroke-width`
- properties on lines, polylines, polygons and paths: `marker-end`, `marker-mid`, `marker-start`
- attributes on all elements: `class`, `id`, `style`, `transform`, `xml:space`
- the viewBox attribute on <svg> and `` elements
- the preserveAspectRatio attribute on <svg>, <image> and `` elements
- transform methods: `translate`, `translateX`, `translateY`, `rotate`, `scale`, `skewX`, `skewY`, `matrix`
- colors: HTML standard names, #xxx, #xxxxxx, rgb(1, 2, 3), rgb(1%, 2%, 3%)
- measurements specified in pt, cm, dm, ft, in, m, mm, yd, pc, %
- fonts: generic CSS fonts, built-in PDF fonts, and any TTF fonts in your fonts path, specified in any of the measurements above plus `em` or `rem`
## CSS
prawn-svg supports CSS, both in `
SVG
end
it "is correctly converted to a call stack" do
element.process
expect(element.calls).to eq [
["fill_color", ["000000"], {}, []],
["transformation_matrix", [1, 0, 0, 1, 0, 0], {}, []],
["transformation_matrix", [1, 0, 0, 1, 0, 0], {}, []],
["save", [], {}, []], ["restore", [], {}, []],
["save", [], {}, []],
["fill_color", ["0000ff"], {}, []],
["fill", [], {}, [
["rectangle", [[0.0, 200.0], 10.0, 10.0], {}, []]
]],
["restore", [], {}, []],
["save", [], {}, []],
["fill_color", ["008000"], {}, []],
["fill", [], {}, [
["rectangle", [[10.0, 200.0], 10.0, 10.0], {}, []]
]],
["restore", [], {}, []],
["save", [], {}, []],
["fill_color", ["ff0000"], {}, []],
["fill", [], {}, [
["rectangle", [[20.0, 200.0], 10.0, 10.0], {}, []]
]],
["restore", [], {}, []],
["save", [], {}, []],
["fill_color", ["ffff00"], {}, []],
["fill", [], {}, [
["rectangle", [[30.0, 200.0], 10.0, 10.0], {}, []]
]],
["restore", [], {}, []]
]
end
end
context "with option :position" do
let(:svg) { IO.read("#{root}/spec/sample_svg/cubic01a.svg") }
it "aligns the image as requested" do
Prawn::Document.generate("#{root}/spec/sample_output/_with_position.pdf") do |prawn|
width = prawn.bounds.width / 3
prawn.svg svg, :width => width, :position => :left
prawn.svg svg, :width => width, :position => :center
prawn.svg svg, :width => width, :position => :right
prawn.svg svg, :width => width, :position => 50
prawn.svg svg, :width => width
end
end
end
context "with option :vposition" do
let(:svg) { IO.read("#{root}/spec/sample_svg/cubic01a.svg") }
it "aligns the image as requested" do
Prawn::Document.generate("#{root}/spec/sample_output/_with_vposition.pdf") do |prawn|
width = prawn.bounds.width / 3
prawn.svg svg, :width => width, :position => :left, :vposition => :bottom
prawn.svg svg, :width => width, :position => :center, :vposition => :center
prawn.svg svg, :width => width, :position => :right, :vposition => :top
prawn.svg svg, :width => width, :position => 50, :vposition => 50
end
end
end
describe "sample file rendering" do
files = Dir["#{root}/spec/sample_svg/*.svg"]
it "has at least 10 SVG sample files to test" do
files.length.should >= 10
end
files.each do |file|
it "renders the #{File.basename file} sample file without warnings or crashing" do
expect(Net::HTTP).to_not receive(:get)
warnings = nil
Prawn::Document.generate("#{root}/spec/sample_output/#{File.basename file}.pdf") do |prawn|
r = prawn.svg IO.read(file), :at => [0, prawn.bounds.top], :width => prawn.bounds.width, :enable_file_requests_with_root => File.dirname(__FILE__) do |doc|
doc.url_loader.add_to_cache("https://raw.githubusercontent.com/mogest/prawn-svg/master/spec/sample_images/mushroom-wide.jpg", IO.read("#{root}/spec/sample_images/mushroom-wide.jpg"))
doc.url_loader.add_to_cache("https://raw.githubusercontent.com/mogest/prawn-svg/master/spec/sample_images/mushroom-long.jpg", IO.read("#{root}/spec/sample_images/mushroom-long.jpg"))
end
warnings = r[:warnings].reject {|w| w =~ /Verdana/ && w =~ /is not a known font/ || w =~ /(render gradients$|waiting on the Prawn project)/}
end
warnings.should == []
end
end
end
describe "multiple file rendering" do
it "renders multiple files on to the same PDF" do
Prawn::Document.generate("#{root}/spec/sample_output/_multiple.pdf") do |prawn|
width = prawn.bounds.width
y = prawn.bounds.top - 12
prawn.draw_text "This is multiple SVGs being output to the same PDF", :at => [0, y]
y -= 12
prawn.svg IO.read("#{root}/spec/sample_svg/arcs01.svg"), :at => [0, y], :width => width / 2
prawn.svg IO.read("#{root}/spec/sample_svg/circle01.svg"), :at => [width / 2, y], :width => width / 2
y -= 120
prawn.draw_text "Here are some more PDFs below", :at => [0, y]
y -= 12
prawn.svg IO.read("#{root}/spec/sample_svg/quad01.svg"), :at => [0, y], :width => width / 3
prawn.svg IO.read("#{root}/spec/sample_svg/rect01.svg"), :at => [width / 3, y], :width => width / 3
prawn.svg IO.read("#{root}/spec/sample_svg/rect02.svg"), :at => [width / 3 * 2, y], :width => width / 3
end
end
end
end
ruby-prawn-svg-0.32.0/spec/prawn/ 0000775 0000000 0000000 00000000000 14021261703 0016554 5 ustar 00root root 0000000 0000000 ruby-prawn-svg-0.32.0/spec/prawn/svg/ 0000775 0000000 0000000 00000000000 14021261703 0017353 5 ustar 00root root 0000000 0000000 ruby-prawn-svg-0.32.0/spec/prawn/svg/attributes/ 0000775 0000000 0000000 00000000000 14021261703 0021541 5 ustar 00root root 0000000 0000000 ruby-prawn-svg-0.32.0/spec/prawn/svg/attributes/opacity_spec.rb 0000664 0000000 0000000 00000004612 14021261703 0024553 0 ustar 00root root 0000000 0000000 require 'spec_helper'
describe Prawn::SVG::Attributes::Opacity do
class OpacityTestElement
include Prawn::SVG::Attributes::Opacity
attr_accessor :properties, :state
def initialize
@properties = ::Prawn::SVG::Properties.new
@state = ::Prawn::SVG::State.new
end
def clamp(value, min_value, max_value)
[[value, min_value].max, max_value].min
end
end
let(:element) { OpacityTestElement.new }
describe "#parse_opacity_attributes_and_call" do
subject { element.parse_opacity_attributes_and_call }
context "with no opacity specified" do
it "does nothing" do
expect(element).not_to receive(:add_call_and_enter)
subject
end
end
context "with opacity" do
it "sets fill and stroke opacity" do
element.properties.opacity = '0.4'
expect(element).to receive(:add_call_and_enter).with('transparent', 0.4, 0.4)
subject
expect(element.state.fill_opacity).to eq 0.4
expect(element.state.stroke_opacity).to eq 0.4
end
end
context "with just fill opacity" do
it "sets fill opacity and sets stroke opacity to 1" do
element.properties.fill_opacity = '0.4'
expect(element).to receive(:add_call_and_enter).with('transparent', 0.4, 1)
subject
expect(element.state.fill_opacity).to eq 0.4
expect(element.state.stroke_opacity).to eq 1
end
end
context "with an existing fill/stroke opacity" do
it "multiplies the new opacity by the old" do
element.state.fill_opacity = 0.5
element.state.stroke_opacity = 0.8
element.properties.fill_opacity = '0.4'
element.properties.stroke_opacity = '0.5'
expect(element).to receive(:add_call_and_enter).with('transparent', 0.2, 0.4)
subject
expect(element.state.fill_opacity).to eq 0.2
expect(element.state.stroke_opacity).to eq 0.4
end
end
context "with stroke, fill, and opacity all specified" do
it "choses the lower of them" do
element.properties.fill_opacity = '0.4'
element.properties.stroke_opacity = '0.6'
element.properties.opacity = '0.5'
expect(element).to receive(:add_call_and_enter).with('transparent', 0.4, 0.5)
subject
expect(element.state.fill_opacity).to eq 0.4
expect(element.state.stroke_opacity).to eq 0.5
end
end
end
end
ruby-prawn-svg-0.32.0/spec/prawn/svg/attributes/transform_spec.rb 0000664 0000000 0000000 00000002625 14021261703 0025120 0 ustar 00root root 0000000 0000000 require 'spec_helper'
describe Prawn::SVG::Attributes::Transform do
class TransformTestElement
include Prawn::SVG::Attributes::Transform
attr_accessor :attributes, :warnings
def initialize
@warnings = []
@attributes = {}
end
end
let(:element) { TransformTestElement.new }
subject { element.send :parse_transform_attribute_and_call }
context "when a non-identity matrix is requested" do
let(:transform) { 'translate(-5.5)' }
it "passes the transform and executes the returned matrix" do
expect(element).to receive(:parse_transform_attribute).with(transform).and_return([1, 2, 3, 4, 5, 6])
expect(element).to receive(:add_call_and_enter).with('transformation_matrix', 1, 2, 3, 4, 5, 6)
element.attributes['transform'] = transform
subject
end
end
context "when an identity matrix is requested" do
let(:transform) { 'translate(0)' }
it "does not execute any commands" do
expect(element).to receive(:parse_transform_attribute).with(transform).and_return([1, 0, 0, 1, 0, 0])
expect(element).not_to receive(:add_call_and_enter)
element.attributes['transform'] = transform
subject
end
end
context "when transform is blank" do
it "does nothing" do
expect(element).not_to receive(:parse_transform_attribute)
expect(element).not_to receive(:add_call_and_enter)
subject
end
end
end
ruby-prawn-svg-0.32.0/spec/prawn/svg/calculators/ 0000775 0000000 0000000 00000000000 14021261703 0021667 5 ustar 00root root 0000000 0000000 ruby-prawn-svg-0.32.0/spec/prawn/svg/calculators/aspect_ratio_spec.rb 0000664 0000000 0000000 00000006644 14021261703 0025715 0 ustar 00root root 0000000 0000000 require File.dirname(__FILE__) + '/../../../spec_helper'
describe Prawn::SVG::Calculators::AspectRatio do
def test(*args)
aspect = Prawn::SVG::Calculators::AspectRatio.new(*args)
[[aspect.width, aspect.height], [aspect.x, aspect.y]]
end
it "handles none" do
expect(test "none", [50,80], [100,100]).to eq [[50, 80], [0, 0]]
expect(test "none", [100,100], [50,80]).to eq [[100, 100], [0, 0]]
end
context "using meet" do
context "with smaller containers than objects" do
let(:coords) { [[50,80], [100,100]] }
it "correctly calculates the result" do
expect(test "xMidYMid meet", *coords).to eq [[50, 50], [0, 15]]
expect(test "xMinYMin meet", *coords).to eq [[50, 50], [0, 0]]
expect(test "xMaxYMax meet", *coords).to eq [[50, 50], [0, 30]]
end
end
context "with bigger containers than objects" do
let(:coords) { [[100,80], [50,50]] }
it "correctly calculates the result" do
expect(test "xMidYMid meet", *coords).to eq [[80, 80], [10, 0]]
expect(test "xMinYMin meet", *coords).to eq [[80, 80], [0, 0]]
expect(test "xMaxYMax meet", *coords).to eq [[80, 80], [20, 0]]
end
end
context "with bigger square containers" do
let(:coords) { [[100,100], [50,80]] }
it "correctly calculates the result" do
expect(test "xMidYMid meet", *coords).to eq [[62.5, 100], [18.75, 0]]
expect(test "xMinYMin meet", *coords).to eq [[62.5, 100], [0, 0]]
expect(test "xMaxYMax meet", *coords).to eq [[62.5, 100], [37.5, 0]]
end
end
context "with oddly shaped containers" do
let(:coords) { [[100,20], [50,50]] }
it "correctly calculates the result" do
expect(test "xMidYMid meet", *coords).to eq [[20, 20], [40, 0]]
expect(test "xMinYMin meet", *coords).to eq [[20, 20], [0, 0]]
expect(test "xMaxYMax meet", *coords).to eq [[20, 20], [80, 0]]
end
end
end
context "using slice" do
context "with smaller containers than objects" do
let(:coords) { [[50,80], [100,100]] }
it "correctly calculates the result" do
expect(test "xMidYMid slice", *coords).to eq [[80, 80], [-15, 0]]
expect(test "xMinYMin slice", *coords).to eq [[80, 80], [0, 0]]
expect(test "xMaxYMax slice", *coords).to eq [[80, 80], [-30, 0]]
end
end
context "with bigger containers than objects" do
let(:coords) { [[100,80], [50,50]] }
it "correctly calculates the result" do
expect(test "xMidYMid slice", *coords).to eq [[100, 100], [0, -10]]
expect(test "xMinYMin slice", *coords).to eq [[100, 100], [0, 0]]
expect(test "xMaxYMax slice", *coords).to eq [[100, 100], [0, -20]]
end
end
context "with oddly shaped containers" do
let(:coords) { [[100,20], [50,50]] }
it "correctly calculates the result" do
expect(test "xMidYMid slice", *coords).to eq [[100, 100], [0, -40]]
expect(test "xMinYMin slice", *coords).to eq [[100, 100], [0, 0]]
expect(test "xMaxYMax slice", *coords).to eq [[100, 100], [0, -80]]
end
end
end
it "defaults to 'xMidYMid meet' if nothing is supplied" do
expect(test "", [50,80], [100,100]).to eq test "xMidYMid meet", [50,80], [100,100]
end
it "defaults to 'xMidYMid meet' if something invalid is supplied" do
expect(test "completely invalid", [50,80], [100,100]).to eq test "xMidYMid meet", [50,80], [100,100]
end
end
ruby-prawn-svg-0.32.0/spec/prawn/svg/calculators/document_sizing_spec.rb 0000664 0000000 0000000 00000012526 14021261703 0026435 0 ustar 00root root 0000000 0000000 require File.dirname(__FILE__) + '/../../../spec_helper'
describe Prawn::SVG::Calculators::DocumentSizing do
let(:attributes) do
{"width" => "150", "height" => "200", "viewBox" => "0 -30 300 800", "preserveAspectRatio" => "xMaxYMid meet"}
end
let(:bounds) { [1200, 800] }
let(:sizing) { Prawn::SVG::Calculators::DocumentSizing.new(bounds, attributes) }
describe "#initialize" do
it "takes bounds and a set of attributes and calls set_from_attributes" do
expect(sizing.instance_variable_get :@bounds).to eq bounds
expect(sizing.instance_variable_get :@document_width).to eq "150"
end
end
describe "#set_from_attributes" do
let(:sizing) { Prawn::SVG::Calculators::DocumentSizing.new(bounds) }
it "sets ivars from the passed-in attributes hash" do
sizing.set_from_attributes(attributes)
expect(sizing.instance_variable_get :@document_width).to eq "150"
expect(sizing.instance_variable_get :@document_height).to eq "200"
expect(sizing.instance_variable_get :@view_box).to eq "0 -30 300 800"
expect(sizing.instance_variable_get :@preserve_aspect_ratio).to eq "xMaxYMid meet"
end
end
describe "#calculate" do
it "calculates the document sizing measurements for a given set of inputs" do
sizing.calculate
expect(sizing.x_offset).to eq(-75 / 0.25)
expect(sizing.y_offset).to eq(-30)
expect(sizing.x_scale).to eq 0.25
expect(sizing.y_scale).to eq 0.25
expect(sizing.viewport_width).to eq 300
expect(sizing.viewport_height).to eq 800
expect(sizing.output_width).to eq 150
expect(sizing.output_height).to eq 200
end
it "scales again based on requested width" do
sizing.requested_width = 75
sizing.calculate
expect(sizing.x_scale).to eq 0.125
expect(sizing.y_scale).to eq 0.125
expect(sizing.viewport_width).to eq 300
expect(sizing.viewport_height).to eq 800
expect(sizing.output_width).to eq 75
expect(sizing.output_height).to eq 100
end
it "scales again based on requested height" do
sizing.requested_height = 100
sizing.calculate
expect(sizing.x_scale).to eq 0.125
expect(sizing.y_scale).to eq 0.125
expect(sizing.viewport_width).to eq 300
expect(sizing.viewport_height).to eq 800
expect(sizing.output_width).to eq 75
expect(sizing.output_height).to eq 100
end
it "correctly handles % values being passed in" do
sizing.document_width = sizing.document_height = "50%"
sizing.calculate
expect(sizing.output_width).to eq 600
expect(sizing.output_height).to eq 400
end
context "when SVG does not specify width and height" do
context "when a viewBox is specified" do
let(:attributes) { {"viewBox" => "0 0 100 200"} }
it "defaults to 100% width and uses the viewbox ratio for height" do
sizing.calculate
expect(sizing.viewport_width).to eq 100
expect(sizing.viewport_height).to eq 200
expect(sizing.output_width).to eq 1200
expect(sizing.output_height).to eq 2400
end
end
context "when a requested width and height are supplied" do
let(:attributes) { {} }
it "uses the requested width and height" do
sizing.requested_width = 550
sizing.requested_height = 400
sizing.calculate
expect(sizing.viewport_width).to eq 550
expect(sizing.viewport_height).to eq 400
expect(sizing.output_width).to eq 550
expect(sizing.output_height).to eq 400
end
end
context "when a viewBox and a requested width/height are supplied" do
let(:attributes) { {"viewBox" => "0 0 100 200"} }
it "uses the requested width and height" do
sizing.requested_width = 550
sizing.requested_height = 400
sizing.calculate
expect(sizing.viewport_width).to eq 100
expect(sizing.viewport_height).to eq 200
expect(sizing.output_width).to eq 550
expect(sizing.output_height).to eq 400
end
end
context "when a viewBox and a requested width is supplied" do
let(:attributes) { {"viewBox" => "0 0 100 200"} }
it "uses the requested width and calculates the height based on the viewBox" do
sizing.requested_width = 550
sizing.calculate
expect(sizing.viewport_width).to eq 100
expect(sizing.viewport_height).to eq 200
expect(sizing.output_width).to eq 550
expect(sizing.output_height).to eq 1100
end
end
context "when a viewBox and a requested height is supplied" do
let(:attributes) { {"viewBox" => "0 0 100 200"} }
it "uses the requested height and calculates the width based on the viewBox" do
sizing.requested_height = 400
sizing.calculate
expect(sizing.viewport_width).to eq 100
expect(sizing.viewport_height).to eq 200
expect(sizing.output_width).to eq 200
expect(sizing.output_height).to eq 400
end
end
context "when neither viewBox nor requested width/height specified" do
let(:attributes) { {} }
it "defaults to 100%" do
sizing.calculate
expect(sizing.output_width).to eq 1200
expect(sizing.output_height).to eq 800
end
end
end
end
end
ruby-prawn-svg-0.32.0/spec/prawn/svg/calculators/pixels_spec.rb 0000664 0000000 0000000 00000004755 14021261703 0024545 0 ustar 00root root 0000000 0000000 require 'spec_helper'
describe Prawn::SVG::Calculators::Pixels do
class TestPixelsCalculator
include Prawn::SVG::Calculators::Pixels
def computed_properties
Struct.new(:numerical_font_size).new(16)
end
[:x, :y, :pixels, :x_pixels, :y_pixels].each { |method| public method }
end
let(:viewport_sizing) do
instance_double(Prawn::SVG::Calculators::DocumentSizing, viewport_width: 600, viewport_height: 400, viewport_diagonal: 500, :requested_width= => nil, :requested_height= => nil)
end
let(:document_sizing) do
instance_double(Prawn::SVG::Calculators::DocumentSizing, output_height: 800)
end
let(:state) { instance_double(Prawn::SVG::State, viewport_sizing: viewport_sizing) }
let(:document) { instance_double(Prawn::SVG::Document, sizing: document_sizing) }
subject { TestPixelsCalculator.new }
before do
allow(subject).to receive(:state).and_return(state)
allow(subject).to receive(:document).and_return(document)
end
describe "#pixels" do
it "converts a variety of measurement units to points" do
expect(subject.pixels(32)).to eq 32.0
expect(subject.pixels(32.0)).to eq 32.0
expect(subject.pixels("32")).to eq 32.0
expect(subject.pixels("32unknown")).to eq 32.0
expect(subject.pixels("32px")).to eq 32.0
expect(subject.pixels("32pt")).to eq 32.0
expect(subject.pixels("32in")).to eq 32.0 * 72
expect(subject.pixels("32pc")).to eq 32.0 * 15
expect(subject.pixels("4em")).to eq 4 * 16
expect(subject.pixels("4ex")).to eq 4 * 8
expect(subject.pixels("32mm")).to be_within(0.0001).of(32 * 72 * 0.0393700787)
expect(subject.pixels("32cm")).to be_within(0.0001).of(32 * 72 * 0.393700787)
expect(subject.pixels("50%")).to eq 250
end
end
describe "#x_pixels" do
it "uses the viewport width for percentages" do
expect(subject.x_pixels("50")).to eq 50
expect(subject.x_pixels("50%")).to eq 300
end
end
describe "#y_pixels" do
it "uses the viewport height for percentages" do
expect(subject.y_pixels("50")).to eq 50
expect(subject.y_pixels("50%")).to eq 200
end
end
describe "#x" do
it "performs the same as #x_pixels" do
expect(subject.x("50")).to eq 50
expect(subject.x("50%")).to eq 300
end
end
describe "#y" do
it "performs the same as #y_pixels but subtracts the pixels from the page height" do
expect(subject.y("50")).to eq 800 - 50
expect(subject.y("50%")).to eq 800 - 200
end
end
end
ruby-prawn-svg-0.32.0/spec/prawn/svg/color_spec.rb 0000664 0000000 0000000 00000004055 14021261703 0022034 0 ustar 00root root 0000000 0000000 require File.dirname(__FILE__) + '/../../spec_helper'
describe Prawn::SVG::Color do
describe "::color_to_hex" do
it "converts #xxx to a hex value" do
Prawn::SVG::Color.color_to_hex("#9ab").should == "99aabb"
end
it "converts #xxxxxx to a hex value" do
Prawn::SVG::Color.color_to_hex("#9ab123").should == "9ab123"
end
it "converts an html colour name to a hex value" do
Prawn::SVG::Color.color_to_hex("White").should == "ffffff"
end
it "converts an rgb string to a hex value" do
Prawn::SVG::Color.color_to_hex("rgb(16, 32, 48)").should == "102030"
Prawn::SVG::Color.color_to_hex("rgb(-5, 50%, 120%)").should == "007fff"
end
it "scans the string and finds the first colour it can parse" do
Prawn::SVG::Color.color_to_hex("function(#someurl, 0) nonexistent rgb( 3 ,4,5 ) white").should == "030405"
end
it "ignores url()s" do
expect(Prawn::SVG::Color.color_to_hex("url(#someplace) red")).to eq 'ff0000'
end
it "returns black if the color doesn't exist" do
expect(Prawn::SVG::Color.color_to_hex("blurble")).to eq '000000'
end
it "returns nil if there's no fallback after a url()" do
expect(Prawn::SVG::Color.color_to_hex("url(#someplace)")).to be nil
end
end
describe "::parse" do
let(:gradients) { {"flan" => flan_gradient, "drob" => drob_gradient} }
let(:flan_gradient) { double }
let(:drob_gradient) { double }
it "returns a list of all colors parsed, ignoring impossible or non-existent colors" do
results = Prawn::SVG::Color.parse("url(#nope) url(#flan) blurble green #123", gradients)
expect(results).to eq [
flan_gradient,
Prawn::SVG::Color::Hex.new("008000"),
Prawn::SVG::Color::Hex.new("112233")
]
end
it "appends black to the list if there aren't any url() references" do
results = Prawn::SVG::Color.parse("blurble green", gradients)
expect(results).to eq [
Prawn::SVG::Color::Hex.new("008000"),
Prawn::SVG::Color::Hex.new("000000")
]
end
end
end
ruby-prawn-svg-0.32.0/spec/prawn/svg/css/ 0000775 0000000 0000000 00000000000 14021261703 0020143 5 ustar 00root root 0000000 0000000 ruby-prawn-svg-0.32.0/spec/prawn/svg/css/font_family_parser_spec.rb 0000664 0000000 0000000 00000001512 14021261703 0025364 0 ustar 00root root 0000000 0000000 require 'spec_helper'
RSpec.describe Prawn::SVG::CSS::FontFamilyParser do
describe "#parse" do
it "correctly handles quotes and escaping" do
tests = {
"" => [],
"font" => ["font"],
"font name, other font" => ["font name", "other font"],
"'font name', other font" => ["font name", "other font"],
"'font, name', other font" => ["font, name", "other font"],
'"font name", other font' => ["font name", "other font"],
'"font, name", other font' => ["font, name", "other font"],
'weird \\" name' => ['weird " name'],
'weird\\, name' => ["weird, name"],
' stupid , spacing ' => ["stupid", "spacing"],
}
tests.each do |string, expected|
expect(Prawn::SVG::CSS::FontFamilyParser.parse(string)).to eq expected
end
end
end
end
ruby-prawn-svg-0.32.0/spec/prawn/svg/css/selector_parser_spec.rb 0000664 0000000 0000000 00000003174 14021261703 0024703 0 ustar 00root root 0000000 0000000 require 'spec_helper'
RSpec.describe Prawn::SVG::CSS::SelectorParser do
describe "::parse" do
it "parses a simple selector" do
expect(described_class.parse("div")).to eq [{name: "div"}]
expect(described_class.parse(".c1")).to eq [{class: ["c1"]}]
end
it "parses a complex selector" do
result = described_class.parse("div#count .c1.c2 > span.large + div~.other:first-child *:nth-child(3)")
expect(result).to eq [
{name: "div", id: ["count"]},
{combinator: :descendant, class: ["c1", "c2"]},
{combinator: :child, name: "span", class: ["large"]},
{combinator: :adjacent, name: "div"},
{combinator: :siblings, class: ["other"], pseudo_class: ["first-child"]},
{combinator: :descendant, name: "*", pseudo_class: ["nth-child(3)"]},
]
end
it "parses attributes" do
expect(described_class.parse("[abc]")).to eq [{attribute: [["abc", nil, nil]]}]
expect(described_class.parse("[abc=123]")).to eq [{attribute: [["abc", '=', '123']]}]
expect(described_class.parse("[abc^=123]")).to eq [{attribute: [["abc", '^=', '123']]}]
expect(described_class.parse("[ abc ^= 123 ]")).to eq [{attribute: [["abc", '^=', '123']]}]
expect(described_class.parse("[abc^='123']")).to eq [{attribute: [["abc", '^=', '123']]}]
expect(described_class.parse("[abc^= '123' ]")).to eq [{attribute: [["abc", '^=', '123']]}]
expect(described_class.parse("[abc^= '123\\'456' ]")).to eq [{attribute: [["abc", '^=', '123\'456']]}]
expect(described_class.parse('[abc^= "123\\"456" ]')).to eq [{attribute: [["abc", '^=', '123"456']]}]
end
end
end
ruby-prawn-svg-0.32.0/spec/prawn/svg/css/stylesheets_spec.rb 0000664 0000000 0000000 00000007674 14021261703 0024074 0 ustar 00root root 0000000 0000000 require 'spec_helper'
RSpec.describe Prawn::SVG::CSS::Stylesheets do
describe "typical usage" do
let(:svg) { <<-SVG }
SVG
it "associates styles with elements" do
result = Prawn::SVG::CSS::Stylesheets.new(CssParser::Parser.new, REXML::Document.new(svg)).load
width_and_styles = result.map { |k, v| [k.attributes["width"].to_i, v] }.sort_by(&:first)
expected = [
[1, [["fill", "#ff0000", false]]],
[2, [["fill", "#ff0000", false], ["fill", "#330000", false], ["fill", "#440000", false], ["fill", "#220000", false]]],
[3, [["fill", "#ff0000", false], ["fill", "#00ff00", false]]],
[4, [["fill", "#ff0000", false], ["fill", "#330000", false], ["fill", "#440000", false], ["fill", "#00ff00", false]]],
]
expected << [5, [["fill", "#ff0000", false], ["fill", "#330000", false], ["fill", "#330000", false], ["fill", "#440000", false], ["fill", "#00ff00", false]]]
expected.concat [
[6, [["fill", "#ff0000", false], ["fill", "#441234", false], ["fill", "#0000ff", false]]],
[7, [["fill", "#550000", false]]],
[8, [["fill", "#660000", false]]],
[9, [["fill", "#770000", false]]],
[10, [["fill", "#880000", false]]],
[11, [["fill", "#990000", false]]],
[12, [["fill", "#aa0000", false]]],
[13, [["fill", "#bb0000", false]]],
[14, [["fill", "#cc0000", false]]],
[15, [["fill", "#dd0000", false]]],
[16, [["fill", "#ee0000", false]]],
]
expect(width_and_styles).to eq(expected)
end
end
describe "style tag parsing" do
let(:svg) do
<<-SVG
SVG
end
it "scans the document for style tags and adds the style information to the css parser" do
css_parser = instance_double(CssParser::Parser)
expect(css_parser).to receive(:add_block!).with("a\n before>\n x y\n inside <>>\n k j\n after\nz")
expect(css_parser).to receive(:add_block!).with("hello")
allow(css_parser).to receive(:each_rule_set)
Prawn::SVG::CSS::Stylesheets.new(css_parser, REXML::Document.new(svg)).load
end
end
end
ruby-prawn-svg-0.32.0/spec/prawn/svg/document_spec.rb 0000664 0000000 0000000 00000001770 14021261703 0022535 0 ustar 00root root 0000000 0000000 require File.dirname(__FILE__) + '/../../spec_helper'
describe Prawn::SVG::Document do
let(:bounds) { [100, 100] }
let(:options) { {} }
describe "#initialize" do
context "when unparsable XML is provided" do
let(:svg) { "this isn't SVG data" }
it "raises an exception" do
expect {
Prawn::SVG::Document.new(svg, bounds, options)
}.to raise_error Prawn::SVG::Document::InvalidSVGData, "The data supplied is not a valid SVG document."
end
end
context "when the user passes in a filename instead of SVG data" do
let(:svg) { "some_file.svg" }
it "raises an exception letting them know what they've done" do
expect {
Prawn::SVG::Document.new(svg, bounds, options)
}.to raise_error Prawn::SVG::Document::InvalidSVGData, "The data supplied is not a valid SVG document. It looks like you've supplied a filename instead; use IO.read(filename) to get the data before you pass it to prawn-svg."
end
end
end
end
ruby-prawn-svg-0.32.0/spec/prawn/svg/elements/ 0000775 0000000 0000000 00000000000 14021261703 0021167 5 ustar 00root root 0000000 0000000 ruby-prawn-svg-0.32.0/spec/prawn/svg/elements/base_spec.rb 0000664 0000000 0000000 00000014654 14021261703 0023452 0 ustar 00root root 0000000 0000000 require 'spec_helper'
describe Prawn::SVG::Elements::Base do
let(:svg) { "" }
let(:document) { Prawn::SVG::Document.new(svg, [800, 600], {}, font_registry: Prawn::SVG::FontRegistry.new("Helvetica" => {:normal => nil})) }
let(:parent_calls) { [] }
let(:element) { Prawn::SVG::Elements::Base.new(document, document.root, parent_calls, fake_state) }
describe "#initialize" do
let(:svg) { '' }
it "adds itself to the elements_by_id hash if an id attribute is supplied" do
element
expect(document.elements_by_id["hello"]).to eq element
end
end
describe "#process" do
it "calls #parse and #apply so subclasses can parse the element" do
expect(element).to receive(:parse).ordered
expect(element).to receive(:apply).ordered
element.process
end
describe "applying calls from the standard attributes" do
let(:svg) do
<<-SVG
SVG
end
it "appends the relevant calls" do
element.process
expect(element.base_calls).to eq [
["transformation_matrix", [2, 0, 0, 2, 0, 0], {}, [
["transparent", [0.5, 1], {}, [
["fill_color", ["ff0000"], {}, []],
["stroke_color", ["0000ff"], {}, []],
["line_width", [5.0], {}, []],
["fill_and_stroke", [], {}, []]
]]
]]
]
end
end
describe "fills and strokes" do
before { element.process }
subject { element.base_calls.last }
context "with neither fill nor stroke" do
let(:svg) { '' }
it { is_expected.to eq ['end_path', [], {}, []] }
end
context "with a fill only" do
let(:svg) { '' }
it { is_expected.to eq ['fill', [], {}, []] }
end
context "with a stroke only" do
let(:svg) { '' }
it { is_expected.to eq ['stroke', [], {}, []] }
end
context "with fill and stroke" do
let(:svg) { '' }
it { is_expected.to eq ['fill_and_stroke', [], {}, []] }
end
context "with fill with evenodd fill rule" do
let(:svg) { '' }
it { is_expected.to eq ['fill', [], {fill_rule: :even_odd}, []] }
end
end
it "appends calls to the parent element" do
expect(element).to receive(:apply) do
element.send :add_call, "test", "argument", kw: 'argument'
end
element.process
expect(element.parent_calls).to eq [["fill", [], {}, [["test", ["argument"], {kw: 'argument'}, []]]]]
end
it "quietly absorbs a SkipElementQuietly exception" do
expect(element).to receive(:parse).and_raise(Prawn::SVG::Elements::Base::SkipElementQuietly)
expect(element).to_not receive(:apply)
element.process
expect(document.warnings).to be_empty
end
it "absorbs a SkipElementError exception, logging a warning" do
expect(element).to receive(:parse).and_raise(Prawn::SVG::Elements::Base::SkipElementError, "hello")
expect(element).to_not receive(:apply)
element.process
expect(document.warnings).to eq ["hello"]
end
end
describe "#apply_colors" do
before do
element.send(:extract_attributes_and_properties)
end
subject { element.send :apply_colors }
it "doesn't change anything if no fill attribute provided" do
expect(element).to_not receive(:add_call)
subject
end
it "doesn't change anything if 'inherit' fill attribute provided" do
element.properties.fill = 'inherit'
expect(element).to_not receive(:add_call)
subject
end
it "doesn't change anything if 'none' fill attribute provided" do
element.properties.fill = 'none'
expect(element).to_not receive(:add_call)
subject
end
it "uses the fill attribute's color" do
expect(element).to receive(:add_call).with('fill_color', 'ff0000')
element.properties.fill = 'red'
subject
end
it "uses black if the fill attribute's color is unparseable" do
expect(element).to receive(:add_call).with('fill_color', '000000')
element.properties.fill = 'blarble'
subject
end
it "uses the color attribute if 'currentColor' fill attribute provided" do
expect(element).to receive(:add_call).with('fill_color', 'ff0000')
element.properties.fill = 'currentColor'
element.state.computed_properties.color = 'red'
subject
end
context "with a color attribute defined on a parent element" do
let(:svg) { '' }
let(:element) { Prawn::SVG::Elements::Root.new(document, document.root, parent_calls) }
let(:flattened_calls) { flatten_calls(element.base_calls) }
it "uses the parent's color element if 'currentColor' fill attribute provided" do
element.process
expect(flattened_calls).to include ['fill_color', ['ff0000'], {}]
expect(flattened_calls).not_to include ['fill_color', ['00ff00'], {}]
end
end
it "computes to 'none' if UnresolvableURLWithNoFallbackError is raised" do
expect(element).to_not receive(:add_call)
element.properties.fill = 'url()'
subject
expect(element.computed_properties.fill).to eq 'none'
end
end
describe "stylesheets" do
let(:svg) { <<-SVG }
SVG
it "applies stylesheet styling but style attributes take precedence" do
document = Prawn::SVG::Document.new(svg, [100, 100], {})
calls = []
element = Prawn::SVG::Elements::Root.new(document, document.root, calls)
element.process
fill_colors = calls.select { |cmd, _, _| cmd == 'fill_color' }.map { |_, args, _| args.first }
expect(fill_colors).to eq ['000000', 'ff0000', '008000', 'ffff00']
end
end
end
ruby-prawn-svg-0.32.0/spec/prawn/svg/elements/gradient_spec.rb 0000664 0000000 0000000 00000010360 14021261703 0024323 0 ustar 00root root 0000000 0000000 require 'spec_helper'
describe Prawn::SVG::Elements::Gradient do
let(:document) { Prawn::SVG::Document.new(svg, [800, 600], {width: 800, height: 600}) }
let(:element) { Prawn::SVG::Elements::Gradient.new(document, document.root, [], fake_state) }
before do
allow(element).to receive(:assert_compatible_prawn_version)
element.process
end
describe "object bounding box with linear gradient" do
let(:svg) do
<<-SVG
SVG
end
it "is stored in the document gradients table" do
expect(document.gradients["flag"]).to eq element
end
it "returns correct gradient arguments for an element" do
arguments = element.gradient_arguments(double(bounding_box: [100, 100, 200, 0]))
expect(arguments).to eq(
from: [100.0, 100.0],
to: [120.0, 0.0],
stops: [[0, "ff0000"], [0.25, "ff0000"], [0.5, "ffffff"], [0.75, "0000ff"], [1, "0000ff"]],
apply_transformations: true,
)
end
it "returns nil if the element doesn't have a bounding box" do
arguments = element.gradient_arguments(double(bounding_box: nil))
expect(arguments).to be nil
end
end
describe "object bounding box with radial gradient" do
let(:svg) do
<<-SVG
SVG
end
it "is stored in the document gradients table" do
expect(document.gradients["flag"]).to eq element
end
it "returns correct gradient arguments for an element" do
arguments = element.gradient_arguments(double(bounding_box: [100, 100, 200, 0]))
expect(arguments).to eq(
from: [150, 80],
to: [100, 80],
r1: 0,
r2: Math.sqrt((0.8 * 100) ** 2 + (0.8 * 100) ** 2),
stops: [[0, "ff0000"], [0.25, "ff0000"], [0.5, "ffffff"], [0.75, "0000ff"], [1, "0000ff"]],
apply_transformations: true,
)
end
end
describe "user space on use with linear gradient" do
let(:svg) do
<<-SVG
SVG
end
it "returns correct gradient arguments for an element" do
arguments = element.gradient_arguments(double)
expect(arguments).to eq(
from: [100.0, 100.0],
to: [200.0, 0.0],
stops: [[0, "ff0000"], [1, "0000ff"]],
apply_transformations: true,
)
end
end
describe "user space on use with radial gradient" do
let(:svg) do
<<-SVG
SVG
end
it "returns correct gradient arguments for an element" do
arguments = element.gradient_arguments(double)
expect(arguments).to eq(
from: [100.0, 100.0],
to: [200.0, 0.0],
r1: 0,
r2: 150,
stops: [[0, "ff0000"], [1, "0000ff"]],
apply_transformations: true,
)
end
end
context "when gradientTransform is specified" do
let(:svg) do
<<-SVG
SVG
end
it "passes in the transform via the apply_transformations option" do
arguments = element.gradient_arguments(double(bounding_box: [0, 0, 10, 10]))
expect(arguments).to eq(
from: [0, 0],
to: [10, 10],
stops: [[0, "ff0000"], [1, "0000ff"]],
apply_transformations: [2, 0, 0, 2, 10, 0],
)
end
end
end
ruby-prawn-svg-0.32.0/spec/prawn/svg/elements/line_spec.rb 0000664 0000000 0000000 00000002706 14021261703 0023462 0 ustar 00root root 0000000 0000000 require 'spec_helper'
RSpec.describe Prawn::SVG::Elements::Line do
let(:document) { Prawn::SVG::Document.new(svg, [800, 600], {width: 800, height: 600}) }
subject do
Prawn::SVG::Elements::Line.new(document, document.root, [], fake_state)
end
context "with attributes specified" do
let(:svg) { '' }
it "renders the line" do
subject.process
expect(subject.base_calls).to eq [
["stroke_color", ["000000"], {}, []],
["stroke", [], {}, [
["move_to", [[5.0, 590.0]], {}, []],
["line_to", [[15.0, 580.0]], {}, []]]
]
]
end
end
context "with no attributes nor stroke specified" do
let(:svg) { '' }
it "outlines a path from 0,0 to 0,0" do
subject.process
expect(subject.base_calls).to eq [
["end_path", [], {}, [
["move_to", [[0, 600]], {}, []],
["line_to", [[0, 600]], {}, []]]
]
]
end
end
context "with a fill specified" do
let(:svg) { '' }
it "ignores the fill" do
subject.process
expect(subject.base_calls).to eq [
["fill_color", ["0000ff"], {}, []],
["stroke_color", ["ff0000"], {}, []],
["stroke", [], {}, [
["move_to", [[0, 600]], {}, []],
["line_to", [[15.0, 580.0]], {}, []]]
]
]
end
end
end
ruby-prawn-svg-0.32.0/spec/prawn/svg/elements/marker_spec.rb 0000664 0000000 0000000 00000005714 14021261703 0024016 0 ustar 00root root 0000000 0000000 require 'spec_helper'
RSpec.describe Prawn::SVG::Elements::Marker do
let(:svg) do
<<-SVG
SVG
end
let(:document) { Prawn::SVG::Document.new(svg, [800, 600], {width: 800, height: 600}) }
let(:state) { Prawn::SVG::State.new }
let(:line_element) do
Prawn::SVG::Elements::Line.new(document, document.root.elements[2], [], state)
end
subject do
Prawn::SVG::Elements::Marker.new(document, document.root.elements[1], [], state)
end
before do
state.viewport_sizing = document.sizing
end
describe "#parse" do
it "forces display none" do
subject.parse
expect(subject.properties.display).to eq 'none'
end
end
describe "#apply_marker" do
it "adds the line and its marker to the call stack" do
subject.process
line_element.process
# We didn't use a marker-* attribute on the tag, that's
# why the apply_marker method wasn't automatically called as part
# of the line_element.process call above.
subject.apply_marker(line_element, point: [10, 10], angle: 45)
# This example follows the example in the SVG 1.1 documentation
# in section 11.6.3.
expect(line_element.base_calls).to eq [
["stroke_color", ["000000"], {}, []],
["line_width", [100.0], {}, []],
["stroke", [], {}, [
["move_to", [[0.0, 600.0]], {}, []],
["line_to", [[10.0, 590.0]], {}, []]
]
],
["save", [], {}, []],
["transformation_matrix", [1, 0, 0, 1, 10, -10], {}, []],
["rotate", [-45], {origin: [0, 600.0]}, [
["transformation_matrix", [100.0, 0, 0, 100.0, 0, 0], {}, []],
["transformation_matrix", [1, 0, 0, 1, -0.0, 1.5], {}, []],
["rectangle", [[-0.5, 600.0], 4.0, 3.0], {}, []],
["clip", [], {}, []],
["transformation_matrix", [0.3, 0, 0, 0.3, 0, 0], {}, []],
["transparent", [1.0, 1.0], {}, [
["stroke_color", ["000000"], {}, []],
["line_width", [100.0], {}, []],
["cap_style", [:butt], {}, []],
["undash", [], {}, []],
["save", [], {}, []],
["fill", [], {}, [
["join_style", [:bevel], {}, []],
["move_to", [[0.0, 600.0]], {}, []],
["line_to", [[10.0, 595.0]], {}, []],
["line_to", [[0.0, 590.0]], {}, []],
["close_path", [], {}, []]
]
],
["restore", [], {}, []],
]
]
]
],
["restore", [], {}, []]
]
end
end
end
ruby-prawn-svg-0.32.0/spec/prawn/svg/elements/path_spec.rb 0000664 0000000 0000000 00000020457 14021261703 0023472 0 ustar 00root root 0000000 0000000 require 'spec_helper'
describe Prawn::SVG::Elements::Path do
let(:source) { double(name: "path", attributes: {}) }
let(:state) { Prawn::SVG::State.new }
let(:path) { Prawn::SVG::Elements::Path.new(nil, source, [], state) }
before do
allow(path).to receive(:attributes).and_return("d" => d)
end
describe "command parsing" do
context "with a valid path" do
let(:d) { "m12.34 -56.78 1 2M4 5 12-34 -.5.7+3 2.3e3 4e4 4e+4 L31,-2e-5L 6,7 Z ZZa50 50 0 100 100" }
it "correctly parses" do
calls = []
allow(path).to receive(:parse_path_command) {|*args| calls << args}
path.parse
expect(calls).to eq [
["m", [[12.34, -56.78], [1, 2]]],
["M", [[4, 5], [12, -34], [-0.5, 0.7], [3, 2.3e3], [4e4, 4e4]]],
["L", [[31, -2e-5]]],
["L", [[6, 7]]],
["Z", []],
["Z", []],
["Z", []],
["a", [[50, 50, 0, 1, 0, 0, 100]]],
]
end
end
context "with m and M commands" do
let(:d) { "M 1,2 3,4 m 5,6 7,8" }
it "treats subsequent points to m/M command as relative/absolute depending on command" do
[
["M", [[1,2],[3,4]]],
["L", [[3,4]]],
["m", [[5,6],[7,8]]],
["l", [[7,8]]]
].each do |args|
expect(path).to receive(:parse_path_command).with(*args).and_call_original
end
path.parse
end
end
context "with an empty path" do
let(:d) { "" }
it "correctly parses" do
expect(path).not_to receive(:run_path_command)
path.parse
end
end
context "with a path with invalid characters" do
let(:d) { "M 10 % 20" }
it "raises" do
expect { path.parse }.to raise_error(Prawn::SVG::Elements::Base::SkipElementError)
end
end
context "with a path with numerical data before a command letter" do
let(:d) { "M 10 % 20" }
it "raises" do
expect { path.parse }.to raise_error(Prawn::SVG::Elements::Base::SkipElementError)
end
end
end
context "when given an M path" do
subject { path.parse; path.commands }
context "with typical arguments" do
let(:d) { "M 100 200 M 200 300 m 10 20" }
it "issues a move command" do
expect(subject).to eq [
Prawn::SVG::Elements::Path::Move.new([100.0, 200.0]),
Prawn::SVG::Elements::Path::Move.new([200.0, 300.0]),
Prawn::SVG::Elements::Path::Move.new([210.0, 320.0]),
]
end
end
context "with only one argument" do
let(:d) { "M 100 200 M 100" }
it "bails out" do
expect(subject).to eq [
Prawn::SVG::Elements::Path::Move.new([100.0, 200.0])
]
end
end
context "with no arguments" do
let(:d) { "M 100 200 M" }
it "bails out" do
expect(subject).to eq [
Prawn::SVG::Elements::Path::Move.new([100.0, 200.0])
]
end
end
end
context "when given an L path" do
subject { path.parse; path.commands }
context "with typical arguments" do
let(:d) { "M 100 200 L 200 300 l 10 20" }
it "issues a line command" do
expect(subject).to eq [
Prawn::SVG::Elements::Path::Move.new([100.0, 200.0]),
Prawn::SVG::Elements::Path::Line.new([200.0, 300.0]),
Prawn::SVG::Elements::Path::Line.new([210.0, 320.0]),
]
end
end
context "with only one argument" do
let(:d) { "M 100 200 L 100" }
it "bails out" do
expect(subject).to eq [
Prawn::SVG::Elements::Path::Move.new([100.0, 200.0])
]
end
end
end
context "when given a C path" do
subject { path.parse; path.commands }
context "with typical arguments" do
let(:d) { "M 100 200 C 10 20 30 40 200 300" }
it "issues a curve command" do
expect(subject).to eq [
Prawn::SVG::Elements::Path::Move.new([100.0, 200.0]),
Prawn::SVG::Elements::Path::Curve.new([200.0, 300.0], [10, 20], [30, 40]),
]
end
end
context "with incomplete arguments" do
let(:d) { "M 100 200 C 10 20 30 40 50" }
it "bails out" do
expect(subject).to eq [
Prawn::SVG::Elements::Path::Move.new([100.0, 200.0])
]
end
end
end
context "when given an S path" do
subject { path.parse; path.commands }
context "with typical arguments" do
let(:d) { "M 100 200 S 30 40 200 300" }
it "issues a curve command" do
expect(subject).to eq [
Prawn::SVG::Elements::Path::Move.new([100.0, 200.0]),
Prawn::SVG::Elements::Path::Curve.new([200.0, 300.0], [100, 200], [30, 40]),
]
end
end
context "with incomplete arguments" do
let(:d) { "M 100 200 S 30 40 50" }
it "bails out" do
expect(subject).to eq [
Prawn::SVG::Elements::Path::Move.new([100.0, 200.0])
]
end
end
end
context "when given a Q path" do
subject { path.parse; path.commands }
context "with typical arguments" do
let(:d) { "M 0 0 Q 600 300 300 600" }
it "issues a curve command" do
expect(subject).to eq [
Prawn::SVG::Elements::Path::Move.new([0, 0]),
Prawn::SVG::Elements::Path::Curve.new([300.0, 600.0], [400, 200], [500, 400])
]
end
end
context "with incomplete arguments" do
let(:d) { "M 100 200 Q 30 40 50" }
it "bails out" do
expect(subject).to eq [
Prawn::SVG::Elements::Path::Move.new([100.0, 200.0])
]
end
end
end
context "when given a T path" do
subject { path.parse; path.commands }
context "with typical arguments" do
let(:d) { "M 0 0 T 300 600" }
it "issues a curve command" do
expect(subject).to eq [
Prawn::SVG::Elements::Path::Move.new([0, 0]),
Prawn::SVG::Elements::Path::Curve.new([300.0, 600.0], [0, 0], [100, 200])
]
end
end
context "with incomplete arguments" do
let(:d) { "M 100 200 T 30" }
it "bails out" do
expect(subject).to eq [
Prawn::SVG::Elements::Path::Move.new([100.0, 200.0])
]
end
end
end
context "when given an A path" do
subject { path.parse; path.commands }
context "that is pretty normal" do
let(:d) { "M 100 200 A 10 10 0 0 1 200 200" }
it "uses bezier curves to approximate an arc path" do
expect(subject).to eq [
Prawn::SVG::Elements::Path::Move.new([100.0, 200.0]),
Prawn::SVG::Elements::Path::Curve.new([150.0, 150.0], [100.0, 172.57081148225683], [122.57081148225683, 150.0]),
Prawn::SVG::Elements::Path::Curve.new([200.0, 200.0], [177.42918851774317, 150.0], [200.0, 172.57081148225683])
]
end
end
context "with an identical start and end point" do
let(:d) { "M 100 200 A 30 30 0 0 1 100 200" }
it "ignores the path" do
expect(subject).to eq [
Prawn::SVG::Elements::Path::Move.new([100.0, 200.0]),
]
end
end
context "with an rx of 0" do
let(:d) { "M 100 200 A 0 10 0 0 1 200 200" }
it "substitutes a line_to" do
expect(subject).to eq [
Prawn::SVG::Elements::Path::Move.new([100.0, 200.0]),
Prawn::SVG::Elements::Path::Line.new([200.0, 200.0])
]
end
end
context "with an ry of 0" do
let(:d) { "M 100 200 A 10 0 0 0 1 200 200" }
it "substitutes a line_to" do
expect(subject).to eq [
Prawn::SVG::Elements::Path::Move.new([100.0, 200.0]),
Prawn::SVG::Elements::Path::Line.new([200.0, 200.0])
]
end
end
context "with incomplete arguments" do
let(:d) { "M 100 200 A 10 20 30 L 10 20" }
it "bails out" do
expect(subject).to eq [
Prawn::SVG::Elements::Path::Move.new([100.0, 200.0])
]
end
end
context "with highly-compressed flags" do
let(:d) { "M100,100a50 50 0 100 100" }
it "correctly parses them" do
expect(subject).to eq [
Prawn::SVG::Elements::Path::Move.new([100.0, 100.0]),
Prawn::SVG::Elements::Path::Curve.new([50.0, 150.0], [72.57081148225681, 100.0], [50.0, 122.57081148225681]),
Prawn::SVG::Elements::Path::Curve.new([99.99999999999999, 200.0], [50.0, 177.42918851774317], [72.5708114822568, 200.0])
]
end
end
end
end
ruby-prawn-svg-0.32.0/spec/prawn/svg/elements/polygon_spec.rb 0000664 0000000 0000000 00000002464 14021261703 0024223 0 ustar 00root root 0000000 0000000 require 'spec_helper'
RSpec.describe Prawn::SVG::Elements::Polygon do
let(:document) { Prawn::SVG::Document.new(svg, [800, 600], {width: 800, height: 600}) }
subject do
Prawn::SVG::Elements::Polygon.new(document, document.root, [], Prawn::SVG::State.new)
end
context "with a valid points attribute" do
let(:svg) { '' }
it "renders the polygon" do
subject.process
expect(subject.base_calls).to eq [
["fill", [], {}, [
["move_to", [[10.0, 590.0]], {}, []],
["line_to", [[20.0, 580.0]], {}, []],
["line_to", [[30.0, 570.0]], {}, []],
["close_path", [], {}, []]]
]
]
end
end
context "with a polygon that has an odd number of arguments" do
let(:svg) { '' }
it "ignores the last one" do
subject.process
expect(subject.base_calls).to eq [
["fill", [], {}, [
["move_to", [[10.0, 590.0]], {}, []],
["line_to", [[20.0, 580.0]], {}, []],
["close_path", [], {}, []]]
]
]
end
end
context "with a polygon that has no arguments" do
let(:svg) { '' }
it "renders nothing" do
subject.process
expect(subject.base_calls).to eq []
end
end
end
ruby-prawn-svg-0.32.0/spec/prawn/svg/elements/polyline_spec.rb 0000664 0000000 0000000 00000002360 14021261703 0024362 0 ustar 00root root 0000000 0000000 require 'spec_helper'
RSpec.describe Prawn::SVG::Elements::Polyline do
let(:document) { Prawn::SVG::Document.new(svg, [800, 600], {width: 800, height: 600}) }
subject do
Prawn::SVG::Elements::Polyline.new(document, document.root, [], Prawn::SVG::State.new)
end
context "with a valid points attribute" do
let(:svg) { '' }
it "renders the polyline" do
subject.process
expect(subject.base_calls).to eq [
["fill", [], {}, [
["move_to", [[10.0, 590.0]], {}, []],
["line_to", [[20.0, 580.0]], {}, []],
["line_to", [[30.0, 570.0]], {}, []]]
]
]
end
end
context "with a polyline that has an odd number of arguments" do
let(:svg) { '' }
it "ignores the last one" do
subject.process
expect(subject.base_calls).to eq [
["fill", [], {}, [
["move_to", [[10.0, 590.0]], {}, []],
["line_to", [[20.0, 580.0]], {}, []]]
]
]
end
end
context "with a polyline that has no arguments" do
let(:svg) { '' }
it "renders nothing" do
subject.process
expect(subject.base_calls).to eq []
end
end
end
ruby-prawn-svg-0.32.0/spec/prawn/svg/elements/text_spec.rb 0000664 0000000 0000000 00000022155 14021261703 0023517 0 ustar 00root root 0000000 0000000 require File.dirname(__FILE__) + '/../../../spec_helper'
describe Prawn::SVG::Elements::Text do
let(:document) { Prawn::SVG::Document.new(svg, [800, 600], {}, font_registry: Prawn::SVG::FontRegistry.new("Helvetica" => {:normal => nil}, "Courier" => {normal: nil}, 'Times-Roman' => {normal: nil})) }
let(:element) { Prawn::SVG::Elements::Text.new(document, document.root, [], fake_state) }
let(:default_style) { {:size=>16, :style=>:normal, :text_anchor=>'start', :at=>[:relative, :relative], :offset=>[0,0]} }
describe "xml:space preserve" do
let(:svg) { %(some\n\t text) }
context "when xml:space is preserve" do
let(:attributes) { ' xml:space="preserve"' }
it "converts newlines and tabs to spaces, and preserves spaces" do
element.process
expect(flatten_calls(element.calls)).to include ["draw_text", ["some text"], {:size=>16, :style=>:normal, :text_anchor=>'start', :at=>[:relative, :relative], :offset=>[0,0]}]
end
end
context "when xml:space is unspecified" do
let(:attributes) { '' }
it "strips space" do
element.process
expect(flatten_calls(element.calls)).to include ["draw_text", ["some text"], {:size=>16, :style=>:normal, :text_anchor=>'start', :at=>[:relative, :relative], :offset=>[0,0]}]
end
end
end
describe "conventional whitespace handling" do
let(:svg) do
<<-SVG
Some text here
More text
Even more
leading goodness
ok
SVG
end
it "correctly apportions white space between the tags" do
element.process
calls = element.calls.flatten
expect(calls).to include "Some text here "
expect(calls).to include "More text"
expect(calls).to include "Even more"
expect(calls).to include " leading goodness "
expect(calls).to include "ok"
end
end
describe "when text-anchor is specified" do
let(:svg) { 'Text' }
let(:element) { Prawn::SVG::Elements::Container.new(document, document.root, [], fake_state) }
it "should inherit text-anchor from parent element" do
element.process
expect(element.calls.flatten).to include(:size => 12.0, :style => :normal, :text_anchor => "middle", :at => [50.0, 586.0], :offset => [0,0])
end
end
describe "letter-spacing" do
let(:svg) { 'spaced' }
it "calls character_spacing with the requested size" do
element.process
expect(element.base_calls).to eq [
["text_group", [], {}, [
["font", ["Helvetica"], {style: :normal}, []],
["character_spacing", [5.0], {}, [
["draw_text", ["spaced"], default_style, []]
]]
]]
]
end
end
describe "underline" do
let(:svg) { 'underlined' }
it "marks the element to be underlined" do
element.process
expect(element.base_calls).to eq [
["text_group", [], {},[
["font", ["Helvetica"], {:style=>:normal}, []],
["draw_text", ["underlined"], default_style.merge(decoration: 'underline'), []]
]]
]
end
end
describe "fill/stroke modes" do
context "with a stroke and no fill" do
let(:svg) { 'stroked' }
it "calls text_rendering_mode with the requested options" do
element.process
expect(element.base_calls).to eq [
["text_group", [], {}, [
["stroke_color", ["ff0000"], {}, []],
["font", ["Helvetica"], {style: :normal}, []],
["text_rendering_mode", [:stroke], {}, [
["draw_text", ["stroked"], default_style, []]
]]
]]
]
end
end
context "with a mixture of everything" do
let(:svg) { 'stroked bothneither' }
it "calls text_rendering_mode with the requested options" do
element.process
expect(element.base_calls).to eq [
["text_group", [], {}, [
["stroke_color", ["ff0000"], {}, []],
["font", ["Helvetica"], {style: :normal}, []],
["text_rendering_mode", [:stroke], {}, [
["draw_text", ["stroked "], default_style, []],
["save", [], {}, []],
["fill_color", ["000000"], {}, []],
["font", ["Helvetica"], {style: :normal}, []],
["text_rendering_mode", [:fill_stroke], {}, [
["draw_text", ["both"], default_style, []]
]],
["restore", [], {}, []],
["save", [], {}, []],
["font", ["Helvetica"], {style: :normal}, []],
["text_rendering_mode", [:invisible], {}, [
["draw_text", ["neither"], default_style, []]
]],
["restore", [], {}, []],
]]
]]
]
end
end
end
describe "font finding" do
context "with a font that exists" do
let(:svg) { 'hello' }
it "finds the font and uses it" do
element.process
expect(flatten_calls(element.base_calls)).to include ['font', ['Courier'], {style: :normal}]
end
end
context "with a font that doesn't exist" do
let(:svg) { 'hello' }
it "uses the fallback font" do
element.process
expect(flatten_calls(element.base_calls)).to include ['font', ['Times-Roman'], {style: :normal}]
end
context "when there is no fallback font" do
before { document.font_registry.installed_fonts.delete("Times-Roman") }
it "doesn't call the font method and logs a warning" do
element.process
expect(element.base_calls.flatten).to_not include 'font'
expect(document.warnings.first).to include "is not a known font"
end
end
end
end
describe "" do
let(:svg) { '' }
let(:element) { Prawn::SVG::Elements::Root.new(document, document.root, [], fake_state) }
it "references the text" do
element.process
expect(flatten_calls(element.base_calls)[9..11]).to eq [
["fill_color", ["ff0000"], {}],
["font", ["Helvetica"], {:style=>:normal}],
["draw_text", ["my reference text"], {:size=>16, :style=>:normal, :text_anchor=>"start", :at=>[10.0, :relative], :offset=>[0,0]}],
]
end
end
describe "dx and dy attributes" do
let(:svg) { 'Hi there, this is a good test' }
it "correctly calculates the positions of the text" do
element.process
expect(flatten_calls(element.base_calls)).to eq [
["text_group", [], {}],
["font", ["Helvetica"], {:style=>:normal}],
["draw_text", ["H"], {:size=>16, :style=>:normal, :text_anchor=>"start", :at=>[10.0, :relative], :offset=>[30.0, 2.0]}],
["draw_text", ["i"], {:size=>16, :style=>:normal, :text_anchor=>"start", :at=>[20.0, :relative], :offset=>[50.0, 0]}],
["draw_text", [" there, this is a good test"], {:size=>16, :style=>:normal, :text_anchor=>"start", :at=>[:relative, :relative], :offset=>[80.0, 0]}]
]
end
end
describe "rotate attribute" do
let(:svg) { 'Hi this ok!' }
it "correctly calculates the positions of the text" do
element.process
expect(flatten_calls(element.base_calls)).to eq [
["text_group", [], {}],
["font", ["Helvetica"], {:style=>:normal}],
["draw_text", ["H"], {:size=>16, :style=>:normal, :text_anchor=>"start", :at=>[:relative, :relative], :offset=>[0, 0], :rotate=>-10.0}],
["draw_text", ["i"], {:size=>16, :style=>:normal, :text_anchor=>"start", :at=>[:relative, :relative], :offset=>[0, 0], :rotate=>-20.0}],
["draw_text", [" "], {:size=>16, :style=>:normal, :text_anchor=>"start", :at=>[:relative, :relative], :offset=>[0, 0], :rotate=>-30.0}],
["save", [], {}],
["font", ["Helvetica"], {:style=>:normal}],
["draw_text", ["this"], {:size=>16, :style=>:normal, :text_anchor=>"start", :at=>[:relative, :relative], :offset=>[0, 0]}],
["restore", [], {}],
["draw_text", [" "], {:size=>16, :style=>:normal, :text_anchor=>"start", :at=>[:relative, :relative], :offset=>[0, 0], :rotate=>-80.0}],
["draw_text", ["o"], {:size=>16, :style=>:normal, :text_anchor=>"start", :at=>[:relative, :relative], :offset=>[0, 0], :rotate=>-90.0}],
["draw_text", ["k"], {:size=>16, :style=>:normal, :text_anchor=>"start", :at=>[:relative, :relative], :offset=>[0, 0], :rotate=>-100.0}],
["draw_text", ["!"], {:size=>16, :style=>:normal, :text_anchor=>"start", :at=>[:relative, :relative], :offset=>[0, 0], :rotate=>-100.0}]
]
end
end
end
ruby-prawn-svg-0.32.0/spec/prawn/svg/font_registry_spec.rb 0000664 0000000 0000000 00000007043 14021261703 0023614 0 ustar 00root root 0000000 0000000 require 'spec_helper'
RSpec.describe Prawn::SVG::FontRegistry do
describe "#load" do
let(:pdf) { Prawn::Document.new }
let(:font_registry) { Prawn::SVG::FontRegistry.new(pdf.font_families) }
it "matches a built in font" do
font_registry.load("blah, 'courier', nothing").name.should == 'Courier'
end
it "matches a default font" do
font_registry.load("serif").name.should == 'Times-Roman'
font_registry.load("blah, serif").name.should == 'Times-Roman'
font_registry.load("blah, serif , test").name.should == 'Times-Roman'
end
if Prawn::SVG::FontRegistry.new({}).installed_fonts["Verdana"]
it "matches a font installed on the system" do
font_registry.load("verdana, sans-serif").name.should == 'Verdana'
font_registry.load("VERDANA, sans-serif").name.should == 'Verdana'
font_registry.load("something, \"Times New Roman\", serif").name.should == "Times New Roman"
font_registry.load("something, Times New Roman, serif").name.should == "Times New Roman"
end
else
it "not running font test because we couldn't find Verdana installed on the system"
end
it "returns nil if it can't find any such font" do
font_registry.load("blah, thing").should be_nil
font_registry.load("").should be_nil
end
end
describe "#installed_fonts" do
let(:ttf) { instance_double(Prawn::SVG::TTF, family: "Awesome Font", subfamily: "Italic") }
let(:ttf2) { instance_double(Prawn::SVG::TTF, family: "Awesome Font", subfamily: "Regular") }
before { Prawn::SVG::FontRegistry.external_font_families.clear }
let(:pdf) do
doc = Prawn::Document.new
doc.font_families.update({
"Awesome Font" => {:italic => "second.ttf", :normal => "file.ttf"}
})
doc
end
let(:font_registry) { Prawn::SVG::FontRegistry.new(pdf.font_families) }
it "does not override existing entries in pdf when loading external fonts" do
expect(Prawn::SVG::FontRegistry).to receive(:font_path).and_return(["x"])
expect(Dir).to receive(:[]).with("x/**/*").and_return(["file.ttf", "second.ttf"])
expect(Prawn::SVG::TTF).to receive(:new).with("file.ttf").and_return(ttf)
expect(Prawn::SVG::TTF).to receive(:new).with("second.ttf").and_return(ttf2)
expect(File).to receive(:file?).at_least(:once).and_return(true)
Prawn::SVG::FontRegistry.load_external_fonts
font_registry.installed_fonts
existing_font = font_registry.installed_fonts["Awesome Font"]
expect(existing_font).to eq(:italic => "second.ttf",:normal => "file.ttf")
end
end
describe "::load_external_fonts" do
let(:ttf) { instance_double(Prawn::SVG::TTF, family: "Awesome Font", subfamily: "Italic") }
let(:ttf2) { instance_double(Prawn::SVG::TTF, family: "Awesome Font", subfamily: "Regular") }
before { Prawn::SVG::FontRegistry.external_font_families.clear }
it "scans the font path and loads in some fonts" do
expect(Prawn::SVG::FontRegistry).to receive(:font_path).and_return(["x"])
expect(Dir).to receive(:[]).with("x/**/*").and_return(["file.ttf", "second.ttf"])
expect(Prawn::SVG::TTF).to receive(:new).with("file.ttf").and_return(ttf)
expect(Prawn::SVG::TTF).to receive(:new).with("second.ttf").and_return(ttf2)
expect(File).to receive(:file?).at_least(:once).and_return(true)
Prawn::SVG::FontRegistry.load_external_fonts
result = Prawn::SVG::FontRegistry.external_font_families
expect(result).to eq("Awesome Font" => {:italic => "file.ttf", :normal => "second.ttf"})
end
end
end
ruby-prawn-svg-0.32.0/spec/prawn/svg/font_spec.rb 0000664 0000000 0000000 00000001223 14021261703 0021656 0 ustar 00root root 0000000 0000000 require File.dirname(__FILE__) + '/../../spec_helper'
describe Prawn::SVG::Font do
describe "#initialize" do
it "maps generic font name to built-in font" do
font_registry = Prawn::SVG::FontRegistry.new({})
font = Prawn::SVG::Font.new('sans-serif', :normal, :normal, font_registry: font_registry)
font.name.should == 'Helvetica'
end
it "preserves generic font name if mapped" do
font_registry = Prawn::SVG::FontRegistry.new('sans-serif' => { normal: 'Times-Roman' })
font = Prawn::SVG::Font.new('sans-serif', :normal, :normal, font_registry: font_registry)
font.name.should == 'sans-serif'
end
end
end
ruby-prawn-svg-0.32.0/spec/prawn/svg/interface_spec.rb 0000664 0000000 0000000 00000011051 14021261703 0022650 0 ustar 00root root 0000000 0000000 require 'spec_helper'
describe Prawn::SVG::Interface do
let(:bounds) { double(width: 800, height: 600, absolute_left: 0, absolute_top: 0) }
let(:prawn) { instance_double(Prawn::Document, font_families: {}, bounds: bounds, cursor: 600) }
let(:svg) { '' }
describe "#initialize" do
describe "invalid option detection" do
it "rejects invalid options when debug is on" do
allow(Prawn).to receive(:debug).and_return(true)
expect {
Prawn::SVG::Interface.new(svg, prawn, :invalid => "option")
}.to raise_error(Prawn::Errors::UnknownOption)
end
it "does nothing if an invalid option is given and debug is off" do
Prawn::SVG::Interface.new(svg, prawn, :invalid => "option")
end
end
end
describe "#draw" do
context "when the sizing object indicates the sizes are invalid" do
let(:interface) { Prawn::SVG::Interface.new('', prawn, {}) }
it "doesn't draw anything and adds a warning" do
interface.draw
expect(interface.document.warnings).to eq ["Zero or negative sizing data means this SVG cannot be rendered"]
end
end
describe "rewrites" do
before do
[:save_font, :bounding_box].each { |message| allow(prawn).to receive(message).and_yield }
allow(prawn).to receive_messages([:move_to, :line_to, :close_path, :fill_color, :stroke_color, :transformation_matrix, :restore_graphics_state])
allow(prawn).to receive(:save_graphics_state) { |&block| block.call if block }
end
context "when fill_and_stroke is issued" do
context "and fill rule is not set" do
let(:interface) { Prawn::SVG::Interface.new('', prawn, {}) }
it "adds content 'B'" do
expect(prawn).to receive(:rectangle).with([0, 100], 10, 10)
expect(prawn).to receive(:add_content).with("W n")
expect(prawn).to receive(:add_content).with("B")
interface.draw
end
end
context "and fill rule is evenodd" do
let(:interface) { Prawn::SVG::Interface.new('', prawn, {}) }
it "adds content 'B*'" do
expect(prawn).to receive(:rectangle).with([0, 100], 10, 10)
expect(prawn).to receive(:add_content).with("W n")
expect(prawn).to receive(:add_content).with("B*")
interface.draw
end
end
end
end
end
describe "#position" do
subject { interface.position }
context "when options[:at] supplied" do
let(:interface) { Prawn::SVG::Interface.new(svg, prawn, at: [1, 2], position: :left) }
it "returns options[:at]" do
expect(subject).to eq [1, 2]
end
end
context "when only a position is supplied" do
let(:interface) { Prawn::SVG::Interface.new(svg, prawn, position: position) }
context "(:left)" do
let(:position) { :left }
it { is_expected.to eq [0, 600] }
end
context "(:center)" do
let(:position) { :center }
it { is_expected.to eq [275, 600] }
end
context "(:right)" do
let(:position) { :right }
it { is_expected.to eq [550, 600] }
end
context "a number" do
let(:position) { 25.5 }
it { is_expected.to eq [25.5, 600] }
end
end
context "when a vposition is supplied" do
let(:interface) { Prawn::SVG::Interface.new(svg, prawn, vposition: vposition) }
context "(:top)" do
let(:vposition) { :top }
it { is_expected.to eq [0, 600] }
end
context "(:center)" do
let(:vposition) { :center }
it { is_expected.to eq [0, 350] }
end
context "(:bottom)" do
let(:vposition) { :bottom }
it { is_expected.to eq [0, 100] }
end
context "a number" do
let(:vposition) { 25.5 }
it { is_expected.to eq [0, 600 - 25.5] }
end
end
end
describe "#sizing and #resize" do
let(:interface) { Prawn::SVG::Interface.new(svg, prawn, {}) }
it "allows the advanced user to resize the SVG after learning about its dimensions" do
expect(interface.sizing.output_width).to eq 250
expect(interface.sizing.output_height).to eq 100
interface.resize(width: 500)
expect(interface.sizing.output_width).to eq 500
expect(interface.sizing.output_height).to eq 200
end
end
end
ruby-prawn-svg-0.32.0/spec/prawn/svg/loaders/ 0000775 0000000 0000000 00000000000 14021261703 0021004 5 ustar 00root root 0000000 0000000 ruby-prawn-svg-0.32.0/spec/prawn/svg/loaders/data_spec.rb 0000664 0000000 0000000 00000002737 14021261703 0023265 0 ustar 00root root 0000000 0000000 require 'spec_helper'
RSpec.describe Prawn::SVG::Loaders::Data do
let(:uri) { URI(url) }
subject { Prawn::SVG::Loaders::Data.new.from_url(url) }
context "with a valid image/png data URL" do
let(:url) { "data:image/png;base64,aGVsbG8=" }
it "loads the data" do
expect(subject).to eq "hello"
end
end
context "with a valid image/jpeg data URL" do
let(:url) { "data:image/jpeg;base64,aGVsbG8=" }
it "loads the data" do
expect(subject).to eq "hello"
end
end
context "with a data URL that has extra metadata" do
let(:url) { "data:image/png;base64;metadata;here,aGVsbG8=" }
it "loads the data" do
expect(subject).to eq "hello"
end
end
context "with a data URL that's uppercase" do
let(:url) { "DATA:IMAGE/PNG;BASE64;METADATA;HERE,aGVsbG8=" }
it "loads the data" do
expect(subject).to eq "hello"
end
end
context "with a URL that's not a data scheme" do
let(:url) { "http://some.host" }
it "returns nil" do
expect(subject).to be nil
end
end
context "with a data URL that's not an image" do
let(:url) { "data:application/pdf;base64,aGVsbG8=" }
it "raises" do
expect { subject }.to raise_error Prawn::SVG::UrlLoader::Error, /image/
end
end
context "with a data URL that's not base64 encoded" do
let(:url) { "data:image/png;base32,agvsbg" }
it "raises" do
expect { subject }.to raise_error Prawn::SVG::UrlLoader::Error, /base64/
end
end
end
ruby-prawn-svg-0.32.0/spec/prawn/svg/loaders/file_spec.rb 0000664 0000000 0000000 00000007761 14021261703 0023275 0 ustar 00root root 0000000 0000000 require 'spec_helper'
RSpec.describe Prawn::SVG::Loaders::File do
let(:root_path) { "." }
let(:fake_root_path) { "/some" }
let(:file_loader) { Prawn::SVG::Loaders::File.new(root_path) }
subject { file_loader.from_url(url) }
context "when an invalid path is supplied" do
let(:root_path) { "/does/not/exist" }
it "raises with an ArgumentError" do
expect { subject }.to raise_error ArgumentError, /is not a directory/
end
end
context "when a relative path is supplied" do
let(:url) { "relative/./path" }
it "loads the file" do
expect(File).to receive(:expand_path).with(".").and_return(fake_root_path)
expect(File).to receive(:expand_path).with("relative/./path", fake_root_path).and_return("#{fake_root_path}/relative/path")
expect(Dir).to receive(:exist?).with(fake_root_path).and_return(true)
expect(File).to receive(:exist?).with("#{fake_root_path}/relative/path").and_return(true)
expect(IO).to receive(:binread).with("#{fake_root_path}/relative/path").and_return("data")
expect(subject).to eq 'data'
end
end
context "when an absolute path without file scheme is supplied" do
let(:url) { "/some/absolute/./path" }
it "loads the file" do
expect(File).to receive(:expand_path).with(".").and_return(fake_root_path)
expect(File).to receive(:expand_path).with(url, fake_root_path).and_return("/some/absolute/path")
expect(Dir).to receive(:exist?).with(fake_root_path).and_return(true)
expect(File).to receive(:exist?).with("/some/absolute/path").and_return(true)
expect(IO).to receive(:binread).with("/some/absolute/path").and_return("data")
expect(subject).to eq 'data'
end
end
context "when an absolute path with file scheme is supplied" do
let(:url) { "file:///some/absolute/./path%20name" }
it "loads the file" do
expect(File).to receive(:expand_path).with(".").and_return(fake_root_path)
expect(File).to receive(:expand_path).with("/some/absolute/./path name", fake_root_path).and_return("/some/absolute/path name")
expect(Dir).to receive(:exist?).with(fake_root_path).and_return(true)
expect(File).to receive(:exist?).with("/some/absolute/path name").and_return(true)
expect(IO).to receive(:binread).with("/some/absolute/path name").and_return("data")
expect(subject).to eq 'data'
end
end
context "when a path outside of our root is specified" do
let(:url) { "/other/absolute/./path" }
it "raises" do
expect(File).to receive(:expand_path).with(".").and_return(fake_root_path)
expect(File).to receive(:expand_path).with(url, fake_root_path).and_return("/other/absolute/path")
expect(Dir).to receive(:exist?).with(fake_root_path).and_return(true)
expect { subject }.to raise_error Prawn::SVG::UrlLoader::Error, /not inside the root path/
end
end
context "when a file: url with a host is specified" do
let(:url) { "file://somewhere/somefile" }
it "raises" do
expect(File).to receive(:expand_path).with(".").and_return(fake_root_path)
expect(Dir).to receive(:exist?).with(fake_root_path).and_return(true)
expect { subject }.to raise_error Prawn::SVG::UrlLoader::Error, /with a host/
end
end
context "when we're running on Windows" do
let(:url) { "file:///c:/path/to/file.png" }
let(:fake_root_path) { "c:/full" }
it "automatically fixes up URI's misparsing of Windows file paths and loads the file" do
expect(File).to receive(:expand_path).with(".").and_return(fake_root_path)
expect(File).to receive(:expand_path).with("c:/path/to/file.png", fake_root_path).and_return("c:/full/path/to/file.png")
expect(Dir).to receive(:exist?).with(fake_root_path).and_return(true)
expect(File).to receive(:exist?).with("c:/full/path/to/file.png").and_return(true)
expect(IO).to receive(:binread).with("c:/full/path/to/file.png").and_return("data")
allow(file_loader).to receive(:windows?).and_return true
expect(subject).to eq 'data'
end
end
end
ruby-prawn-svg-0.32.0/spec/prawn/svg/loaders/web_spec.rb 0000664 0000000 0000000 00000001747 14021261703 0023131 0 ustar 00root root 0000000 0000000 require 'spec_helper'
RSpec.describe Prawn::SVG::Loaders::Web do
let(:url) { "http://hello.there/path" }
let(:uri) { URI(url) }
subject { Prawn::SVG::Loaders::Web.new.from_url(url) }
it "loads an HTTP URL" do
expect(Net::HTTP).to receive(:get).with(uri).and_return("hello!")
expect(subject).to eq "hello!"
end
context "with an https URL" do
let(:url) { "https://hello.there/path"}
it "loads the HTTPS URL" do
expect(Net::HTTP).to receive(:get).with(uri).and_return("hello!")
expect(subject).to eq "hello!"
end
end
context "when the HTTP call raises" do
it "re-raises the error as UrlLoader errors" do
expect(Net::HTTP).to receive(:get).with(uri).and_raise(SocketError, "argh")
expect { subject }.to raise_error Prawn::SVG::UrlLoader::Error, 'argh'
end
end
context "with a non-http, non-https URL" do
let(:url) { "mailto:someone@something" }
it "returns nil" do
expect(subject).to be nil
end
end
end
ruby-prawn-svg-0.32.0/spec/prawn/svg/pathable_spec.rb 0000664 0000000 0000000 00000005135 14021261703 0022476 0 ustar 00root root 0000000 0000000 require 'spec_helper'
RSpec.describe Prawn::SVG::Pathable do
class FakeElement < Prawn::SVG::Elements::Base
include Prawn::SVG::Pathable
def initialize(*args)
super
@properties = Struct.new(:marker_start, :marker_mid, :marker_end).new
end
public :apply_commands
public :apply_markers
def commands
@commands ||= [
Prawn::SVG::Pathable::Move.new([10, 10]),
Prawn::SVG::Pathable::Line.new([20, 20]),
Prawn::SVG::Pathable::Curve.new([30, 30], [25, 20], [25, 25]),
Prawn::SVG::Pathable::Close.new([10, 10])
]
end
end
let(:document) { Prawn::SVG::Document.new("", [800, 600], {width: 800, height: 600}) }
let(:state) { Prawn::SVG::State.new }
subject do
FakeElement.new(document, document.root, [], state)
end
describe "#bounding_box" do
it "determines the bounding box using the translated commands" do
expect(subject.bounding_box).to eq [10, 590, 30, 570]
end
end
describe "#apply_commands" do
it "applies the commands to the call stack" do
subject.apply_commands
expect(subject.base_calls).to eq [
["move_to", [[10.0, 590.0]], {}, []],
["line_to", [[20.0, 580.0]], {}, []],
["curve_to", [[30.0, 570.0]], {bounds: [[25.0, 580.0], [25.0, 575.0]]}, []],
["close_path", [], {}, []]
]
end
end
describe "#apply_markers" do
let(:marker) { instance_double(Prawn::SVG::Elements::Marker, name: "marker") }
before do
document.elements_by_id["triangle"] = marker
end
context "with marker-start attribute specified" do
before do
subject.properties.marker_start = "url(#triangle)"
end
it "calls apply_marker on the marker" do
expect(marker).to receive(:apply_marker).with(subject, point: [10, 10], angle: 45)
subject.apply_markers
end
end
context "with marker-mid attribute specified" do
before do
subject.properties.marker_mid = "url(#triangle)"
end
it "calls apply_marker on the marker" do
expect(marker).to receive(:apply_marker).with(subject, point: [20, 20], angle: 45)
expect(marker).to receive(:apply_marker).with(subject, point: [30, 30], angle: -45)
subject.apply_markers
end
end
context "with marker-end attribute specified" do
before do
subject.properties.marker_end = "url(#triangle)"
end
it "calls apply_marker on the marker" do
expect(marker).to receive(:apply_marker).with(subject, point: [10, 10], angle: -45)
subject.apply_markers
end
end
end
end
ruby-prawn-svg-0.32.0/spec/prawn/svg/properties_spec.rb 0000664 0000000 0000000 00000012476 14021261703 0023120 0 ustar 00root root 0000000 0000000 require 'spec_helper'
RSpec.describe Prawn::SVG::Properties do
subject { Prawn::SVG::Properties.new }
describe "#load_default_stylesheet" do
it "loads in the defaults and returns self" do
expect(subject.load_default_stylesheet).to eq subject
expect(subject.font_family).to eq 'sans-serif'
end
end
describe "#set" do
it "sets a property" do
result = subject.set('color', 'red')
expect(result).to be
expect(subject.color).to eq 'red'
end
it "handles property names that are not lower case" do
result = subject.set('COLor', 'red')
expect(result).to be
expect(subject.color).to eq 'red'
end
it "right-cases and strips keywords" do
subject.set('stroke-linecap', ' Round ')
expect(subject.stroke_linecap).to eq 'round'
end
it "doesn't right-case values that aren't recognised as keywords" do
subject.set('color', 'Red')
expect(subject.color).to eq 'Red'
end
it "sets a 'keyword restricted' property to its default if the value doesn't match a keyword" do
subject.set('stroke-linecap', 'invalid')
expect(subject.stroke_linecap).to eq 'butt'
end
end
describe "#load_hash" do
it "uses #set to load in a hash of properties" do
subject.load_hash("stroke" => "blue", "fill" => "green", 'stroke-linecap' => "Round")
expect(subject.stroke).to eq 'blue'
expect(subject.fill).to eq 'green'
expect(subject.stroke_linecap).to eq 'round'
end
end
describe "#compute_properties" do
let(:other) { Prawn::SVG::Properties.new }
it "auto-inherits inheritable properties when the property is not supplied" do
subject.set('color', 'green')
subject.compute_properties(other)
expect(subject.color).to eq 'green'
end
it "doesn't auto-inherit non-inheritable properties" do
subject.set('display', 'none')
subject.compute_properties(other)
expect(subject.display).to eq 'inline'
end
it "inherits non-inheritable properties when specifically asked to" do
subject.set('display', 'none')
other.set('display', 'inherit')
subject.compute_properties(other)
expect(subject.display).to eq 'none'
end
it "uses the new property value" do
subject.set('color', 'green')
other.set('color', 'red')
subject.compute_properties(other)
expect(subject.color).to eq 'red'
end
describe "font size" do
before do
subject.font_size = "15"
other.font_size = font_size
end
context "when given a % as a font-size" do
let(:font_size) { "120%" }
it "calculates the new font size" do
subject.compute_properties(other)
expect(subject.font_size).to eq "18.0"
end
end
context "when given 'larger' as a font-size" do
let(:font_size) { "larger" }
it "calculates the new font size" do
subject.compute_properties(other)
expect(subject.font_size).to eq "19.0"
end
end
context "when given 'smaller' as a font-size" do
let(:font_size) { "smaller" }
it "calculates the new font size" do
subject.compute_properties(other)
expect(subject.font_size).to eq "11.0"
end
end
context "when given a value in 'em' as a font-size" do
let(:font_size) { "2.5em" }
it "calculates the new font size" do
subject.compute_properties(other)
expect(subject.font_size).to eq "37.5"
end
end
context "when given a value in 'rem' as a font-size" do
let(:font_size) { "2.5rem" }
it "calculates the new font size" do
subject.compute_properties(other)
expect(subject.font_size).to eq "40.0"
end
end
context "when given a value in 'px' as a font-size" do
let(:font_size) { "19.5px" }
it "uses the font size specified" do
subject.compute_properties(other)
expect(subject.font_size).to eq "19.5"
end
end
context "when given a value in 'pt' as a font-size" do
let(:font_size) { "19.5pt" }
it "uses the font size specified" do
subject.compute_properties(other)
expect(subject.font_size).to eq "19.5"
end
end
context "when given a value without units as a font-size" do
let(:font_size) { "19.5" }
it "uses the font size specified" do
subject.compute_properties(other)
expect(subject.font_size).to eq "19.5"
end
end
context "when given the keyword 'inherit' as a font-size" do
let(:font_size) { "inherit" }
it "uses the font size specified by the parent" do
subject.compute_properties(other)
expect(subject.font_size).to eq "15"
end
end
end
end
describe "#numerical_font_size" do
context "when the font size is a number" do
before { subject.font_size = "16.5" }
it "returns the number as a float" do
expect(subject.numerical_font_size).to eq 16.5
end
end
context "when the font size is one of the keyword size specifiers" do
before { subject.font_size = "x-large" }
it "returns the font size number corresponding with the keyword" do
expect(subject.numerical_font_size).to eq 24
end
end
end
end
ruby-prawn-svg-0.32.0/spec/prawn/svg/transform_parser_spec.rb 0000664 0000000 0000000 00000004535 14021261703 0024310 0 ustar 00root root 0000000 0000000 require 'spec_helper'
RSpec.describe Prawn::SVG::TransformParser do
class Test
include Prawn::SVG::Calculators::Pixels
include Prawn::SVG::TransformParser
State = Struct.new(:viewport_sizing)
Properties = Struct.new(:numerical_font_size)
Document = Struct.new(:sizing)
def document
Document.new(_sizing)
end
def state
State.new(_sizing)
end
def computed_properties
Properties.new(14)
end
def _sizing
Prawn::SVG::Calculators::DocumentSizing.new([1000, 800])
end
end
subject { Test.new.parse_transform_attribute(transform) }
context "with no transform" do
let(:transform) { '' }
it { is_expected.to eq [1, 0, 0, 1, 0, 0] }
end
context "with translate" do
let(:transform) { 'translate(10 20)' }
it { is_expected.to eq [1, 0, 0, 1, 10, -20] }
end
context "with single argument translate" do
let(:transform) { 'translate(10)' }
it { is_expected.to eq [1, 0, 0, 1, 10, 0] }
end
context "with translateX" do
let(:transform) { 'translateX(10)' }
it { is_expected.to eq [1, 0, 0, 1, 10, 0] }
end
context "with translateY" do
let(:transform) { 'translateY(10)' }
it { is_expected.to eq [1, 0, 0, 1, 0, -10] }
end
let(:sin30) { Math.sin(30 * Math::PI / 180.0) }
let(:cos30) { Math.cos(30 * Math::PI / 180.0) }
let(:tan30) { Math.tan(30 * Math::PI / 180.0) }
context "with single argument rotate" do
let(:transform) { 'rotate(30)' }
it { is_expected.to eq [cos30, -sin30, sin30, cos30, 0, 0] }
end
context "with triple argument rotate" do
let(:transform) { 'rotate(30 100 200)' }
it { is_expected.to eq [cos30, -sin30, sin30, cos30, 113.39745962155611, 23.205080756887753] }
end
context "with scale" do
let(:transform) { 'scale(1.5)' }
it { is_expected.to eq [1.5, 0, 0, 1.5, 0, 0] }
end
context "with skewX" do
let(:transform) { 'skewX(30)' }
it { is_expected.to eq [1, 0, -tan30, 1, 0, 0] }
end
context "with skewY" do
let(:transform) { 'skewY(30)' }
it { is_expected.to eq [1, -tan30, 0, 1, 0, 0] }
end
context "with matrix" do
let(:transform) { 'matrix(1 2 3 4 5 6)' }
it { is_expected.to eq [1, -2, -3, 4, 5, -6] }
end
context "with multiple" do
let(:transform) { 'scale(2) translate(7) scale(3)' }
it { is_expected.to eq [6, 0, 0, 6, 14, 0] }
end
end
ruby-prawn-svg-0.32.0/spec/prawn/svg/ttf_spec.rb 0000664 0000000 0000000 00000001543 14021261703 0021512 0 ustar 00root root 0000000 0000000 require 'spec_helper'
RSpec.describe Prawn::SVG::TTF do
subject { Prawn::SVG::TTF.new(filename) }
context "with a truetype font" do
let(:filename) { "#{File.dirname(__FILE__)}/../../sample_ttf/OpenSans-SemiboldItalic.ttf" }
it "gets the English family and subfamily from the font file" do
expect(subject.family).to eq 'Open Sans'
expect(subject.subfamily).to eq 'Semibold Italic'
end
end
context "with a file that isn't a TTF" do
let(:filename) { __FILE__ }
it "has a nil family and subfamily" do
expect(subject.family).to be nil
expect(subject.subfamily).to be nil
end
end
context "with a file that doesn't exist" do
let(:filename) { "does_not_exist" }
it "has a nil family and subfamily" do
expect(subject.family).to be nil
expect(subject.subfamily).to be nil
end
end
end
ruby-prawn-svg-0.32.0/spec/prawn/svg/url_loader_spec.rb 0000664 0000000 0000000 00000007457 14021261703 0023057 0 ustar 00root root 0000000 0000000 require 'spec_helper'
describe Prawn::SVG::UrlLoader do
let(:enable_cache) { true }
let(:enable_web) { true }
let(:enable_file) { "." }
let(:loader) { Prawn::SVG::UrlLoader.new(enable_cache: enable_cache, enable_web: enable_web, enable_file_with_root: enable_file) }
describe "#initialize" do
it "sets options" do
expect(loader.enable_cache).to be true
end
end
describe "#load" do
let(:url) { "http://hello/there" }
let(:data_loader) { instance_double(Prawn::SVG::Loaders::Data) }
let(:web_loader) { instance_double(Prawn::SVG::Loaders::Web) }
let(:file_loader) { instance_double(Prawn::SVG::Loaders::File) }
before do
allow(Prawn::SVG::Loaders::Data).to receive(:new).and_return(data_loader)
allow(Prawn::SVG::Loaders::Web).to receive(:new).and_return(web_loader)
allow(Prawn::SVG::Loaders::File).to receive(:new).with(enable_file).and_return(file_loader)
end
subject { loader.load(url) }
it "calls the Data loader and returns its output if successful" do
expect(data_loader).to receive(:from_url).with(url).and_return("data")
expect(web_loader).not_to receive(:from_url)
expect(subject).to eq 'data'
end
it "calls the Web loader if the Data loader returns nothing, and returns its output if successful" do
expect(data_loader).to receive(:from_url).with(url)
expect(web_loader).to receive(:from_url).with(url).and_return("data")
expect(subject).to eq 'data'
end
it "calls the File loader if the Data and Web loaders return nothing, and returns its output if successful" do
expect(data_loader).to receive(:from_url).with(url)
expect(web_loader).to receive(:from_url).with(url)
expect(file_loader).to receive(:from_url).with(url).and_return("data")
expect(subject).to eq 'data'
end
it "raises if none of the loaders return any data" do
expect(data_loader).to receive(:from_url).with(url)
expect(web_loader).to receive(:from_url).with(url)
expect(file_loader).to receive(:from_url).with(url)
expect { subject }.to raise_error(Prawn::SVG::UrlLoader::Error, /No handler available/)
end
context "when caching is enabled" do
it "caches the result" do
expect(data_loader).to receive(:from_url).with(url).and_return("data")
expect(subject).to eq 'data'
expect(loader.retrieve_from_cache(url)).to eq 'data'
end
end
context "when caching is disabled" do
let(:enable_cache) { false }
it "does not cache the result" do
expect(data_loader).to receive(:from_url).with(url).and_return("data")
expect(subject).to eq 'data'
expect(loader.retrieve_from_cache(url)).to be nil
end
end
context "when the cache is populated" do
before { loader.add_to_cache(url, 'data') }
it "returns the cached value without calling a loader" do
expect(data_loader).not_to receive(:from_url)
expect(web_loader).not_to receive(:from_url)
expect(subject).to eq 'data'
end
end
context "when web requests are disabled" do
let(:enable_web) { false }
it "doesn't use the web loader" do
expect(data_loader).to receive(:from_url)
expect(web_loader).not_to receive(:from_url)
expect(file_loader).to receive(:from_url)
expect { subject }.to raise_error(Prawn::SVG::UrlLoader::Error, /No handler available/)
end
end
context "when file requests are disabled" do
let(:enable_file) { nil }
it "doesn't use the file loader" do
expect(data_loader).to receive(:from_url)
expect(web_loader).to receive(:from_url)
expect(file_loader).not_to receive(:from_url)
expect { subject }.to raise_error(Prawn::SVG::UrlLoader::Error, /No handler available/)
end
end
end
end
ruby-prawn-svg-0.32.0/spec/sample_images/ 0000775 0000000 0000000 00000000000 14021261703 0020233 5 ustar 00root root 0000000 0000000 ruby-prawn-svg-0.32.0/spec/sample_images/mushroom-long.jpg 0000664 0000000 0000000 00000055643 14021261703 0023560 0 ustar 00root root 0000000 0000000 JFIF H H ICC_PROFILE mntrRGB XYZ $ acsp - )=ޯUxBʃ9
desc D ybXYZ bTRC dmdd gXYZ
h gTRC lumi
| meas
$bkpt
rXYZ
rTRC tech
vued
wtpt p cprt 7chad ,desc sRGB IEC61966-2-1 black scaled XYZ $ curv
# ( - 2 7 ; @ E J O T Y ^ c h m r w |
%+28>ELRY`gnu|&/8AKT]gqz !-8COZfr~ -;HUcq~
+:IXgw'7HYj{+=Oat2FZn % : O d y
'
=
T
j
"9Qi*C\u
&
@
Z
t
.Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i A l !!H!u!!!"'"U"""#
#8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''(
(?(q(())8)k))**5*h**++6+i++,,9,n,,--A-v--..L.../$/Z///050l0011J1112*2c223
3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JKKSKKL*LrLMMJMMN%NnNO OIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G
k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4
uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD- u`ֲK³8%yhYѹJº;.!
zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs
2F[p(@Xr4Pm8Ww)Kmdesc .IEC 61966-2-1 Default RGB Colour Space - sRGB XYZ b XYZ P meas XYZ 3 XYZ o 8 sig CRT desc -Reference Viewing Condition in IEC 61966-2-1 XYZ -text Copyright International Color Consortium, 2009 sf32 D &