prawn-svg 0.34.2 → 0.35.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/lint.yml +19 -0
- data/.github/workflows/test.yml +14 -27
- data/.gitignore +0 -1
- data/.rubocop.yml +86 -0
- data/.rubocop_todo.yml +51 -0
- data/Gemfile +4 -3
- data/Gemfile.lock +81 -0
- data/README.md +1 -1
- data/Rakefile +1 -1
- data/lib/prawn/svg/attributes/clip_path.rb +3 -3
- data/lib/prawn/svg/attributes/opacity.rb +3 -3
- data/lib/prawn/svg/attributes/stroke.rb +9 -9
- data/lib/prawn/svg/attributes/transform.rb +2 -2
- data/lib/prawn/svg/attributes.rb +1 -1
- data/lib/prawn/svg/calculators/arc_to_bezier_curve.rb +17 -15
- data/lib/prawn/svg/calculators/aspect_ratio.rb +16 -14
- data/lib/prawn/svg/calculators/document_sizing.rb +9 -10
- data/lib/prawn/svg/calculators/pixels.rb +8 -5
- data/lib/prawn/svg/color.rb +209 -212
- data/lib/prawn/svg/css/font_family_parser.rb +2 -2
- data/lib/prawn/svg/css/selector_parser.rb +39 -35
- data/lib/prawn/svg/css/stylesheets.rb +24 -24
- data/lib/prawn/svg/css/values_parser.rb +68 -0
- data/lib/prawn/svg/document.rb +6 -5
- data/lib/prawn/svg/elements/base.rb +29 -34
- data/lib/prawn/svg/elements/circle.rb +4 -4
- data/lib/prawn/svg/elements/clip_path.rb +0 -1
- data/lib/prawn/svg/elements/depth_first_base.rb +6 -6
- data/lib/prawn/svg/elements/ellipse.rb +3 -4
- data/lib/prawn/svg/elements/gradient.rb +49 -51
- data/lib/prawn/svg/elements/image.rb +5 -5
- data/lib/prawn/svg/elements/marker.rb +5 -5
- data/lib/prawn/svg/elements/path.rb +46 -47
- data/lib/prawn/svg/elements/polygon.rb +1 -1
- data/lib/prawn/svg/elements/polyline.rb +2 -2
- data/lib/prawn/svg/elements/rect.rb +3 -3
- data/lib/prawn/svg/elements/text.rb +1 -1
- data/lib/prawn/svg/elements/text_component.rb +22 -22
- data/lib/prawn/svg/elements/use.rb +3 -7
- data/lib/prawn/svg/elements/viewport.rb +1 -3
- data/lib/prawn/svg/elements.rb +30 -29
- data/lib/prawn/svg/extension.rb +2 -1
- data/lib/prawn/svg/font.rb +7 -7
- data/lib/prawn/svg/font_registry.rb +13 -13
- data/lib/prawn/svg/gradients.rb +3 -2
- data/lib/prawn/svg/interface.rb +4 -3
- data/lib/prawn/svg/loaders/data.rb +2 -2
- data/lib/prawn/svg/loaders/file.rb +12 -14
- data/lib/prawn/svg/loaders/web.rb +4 -8
- data/lib/prawn/svg/pathable.rb +41 -37
- data/lib/prawn/svg/properties.rb +34 -33
- data/lib/prawn/svg/renderer.rb +7 -7
- data/lib/prawn/svg/state.rb +1 -1
- data/lib/prawn/svg/transform_parser.rb +5 -5
- data/lib/prawn/svg/ttf.rb +21 -17
- data/lib/prawn/svg/url_loader.rb +1 -1
- data/lib/prawn/svg/version.rb +1 -1
- data/lib/prawn-svg.rb +1 -0
- data/prawn-svg.gemspec +5 -7
- data/spec/integration_spec.rb +77 -70
- data/spec/prawn/svg/attributes/opacity_spec.rb +11 -15
- data/spec/prawn/svg/attributes/transform_spec.rb +6 -6
- data/spec/prawn/svg/calculators/aspect_ratio_spec.rb +50 -50
- data/spec/prawn/svg/calculators/document_sizing_spec.rb +35 -35
- data/spec/prawn/svg/calculators/pixels_spec.rb +31 -30
- data/spec/prawn/svg/color_spec.rb +31 -31
- data/spec/prawn/svg/css/font_family_parser_spec.rb +12 -12
- data/spec/prawn/svg/css/selector_parser_spec.rb +21 -21
- data/spec/prawn/svg/css/stylesheets_spec.rb +51 -45
- data/spec/prawn/svg/css/values_parser_spec.rb +16 -0
- data/spec/prawn/svg/document_spec.rb +15 -14
- data/spec/prawn/svg/elements/base_spec.rb +39 -34
- data/spec/prawn/svg/elements/gradient_spec.rb +39 -39
- data/spec/prawn/svg/elements/line_spec.rb +22 -22
- data/spec/prawn/svg/elements/marker_spec.rb +36 -40
- data/spec/prawn/svg/elements/path_spec.rb +134 -110
- data/spec/prawn/svg/elements/polygon_spec.rb +18 -18
- data/spec/prawn/svg/elements/polyline_spec.rb +16 -16
- data/spec/prawn/svg/elements/text_spec.rb +149 -127
- data/spec/prawn/svg/font_registry_spec.rb +34 -34
- data/spec/prawn/svg/font_spec.rb +4 -4
- data/spec/prawn/svg/interface_spec.rb +47 -39
- data/spec/prawn/svg/loaders/data_spec.rb +21 -21
- data/spec/prawn/svg/loaders/file_spec.rb +43 -40
- data/spec/prawn/svg/loaders/web_spec.rb +15 -15
- data/spec/prawn/svg/pathable_spec.rb +21 -21
- data/spec/prawn/svg/properties_spec.rb +51 -51
- data/spec/prawn/svg/transform_parser_spec.rb +12 -12
- data/spec/prawn/svg/ttf_spec.rb +5 -5
- data/spec/prawn/svg/url_loader_spec.rb +25 -23
- data/spec/spec_helper.rb +4 -4
- metadata +21 -146
@@ -1,35 +1,35 @@
|
|
1
|
-
require File.dirname(__FILE__)
|
1
|
+
require "#{File.dirname(__FILE__)}/../../../spec_helper"
|
2
2
|
|
3
3
|
describe Prawn::SVG::Calculators::DocumentSizing do
|
4
4
|
let(:attributes) do
|
5
|
-
{
|
5
|
+
{ 'width' => '150', 'height' => '200', 'viewBox' => '0 -30 300 800', 'preserveAspectRatio' => 'xMaxYMid meet' }
|
6
6
|
end
|
7
7
|
|
8
8
|
let(:bounds) { [1200, 800] }
|
9
9
|
|
10
10
|
let(:sizing) { Prawn::SVG::Calculators::DocumentSizing.new(bounds, attributes) }
|
11
11
|
|
12
|
-
describe
|
13
|
-
it
|
14
|
-
expect(sizing.instance_variable_get
|
15
|
-
expect(sizing.instance_variable_get
|
12
|
+
describe '#initialize' do
|
13
|
+
it 'takes bounds and a set of attributes and calls set_from_attributes' do
|
14
|
+
expect(sizing.instance_variable_get(:@bounds)).to eq bounds
|
15
|
+
expect(sizing.instance_variable_get(:@document_width)).to eq '150'
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
-
describe
|
19
|
+
describe '#set_from_attributes' do
|
20
20
|
let(:sizing) { Prawn::SVG::Calculators::DocumentSizing.new(bounds) }
|
21
21
|
|
22
|
-
it
|
22
|
+
it 'sets ivars from the passed-in attributes hash' do
|
23
23
|
sizing.set_from_attributes(attributes)
|
24
|
-
expect(sizing.instance_variable_get
|
25
|
-
expect(sizing.instance_variable_get
|
26
|
-
expect(sizing.instance_variable_get
|
27
|
-
expect(sizing.instance_variable_get
|
24
|
+
expect(sizing.instance_variable_get(:@document_width)).to eq '150'
|
25
|
+
expect(sizing.instance_variable_get(:@document_height)).to eq '200'
|
26
|
+
expect(sizing.instance_variable_get(:@view_box)).to eq '0 -30 300 800'
|
27
|
+
expect(sizing.instance_variable_get(:@preserve_aspect_ratio)).to eq 'xMaxYMid meet'
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
|
-
describe
|
32
|
-
it
|
31
|
+
describe '#calculate' do
|
32
|
+
it 'calculates the document sizing measurements for a given set of inputs' do
|
33
33
|
sizing.calculate
|
34
34
|
expect(sizing.x_offset).to eq(-75 / 0.25)
|
35
35
|
expect(sizing.y_offset).to eq(-30)
|
@@ -41,7 +41,7 @@ describe Prawn::SVG::Calculators::DocumentSizing do
|
|
41
41
|
expect(sizing.output_height).to eq 200
|
42
42
|
end
|
43
43
|
|
44
|
-
it
|
44
|
+
it 'scales again based on requested width' do
|
45
45
|
sizing.requested_width = 75
|
46
46
|
sizing.calculate
|
47
47
|
expect(sizing.x_scale).to eq 0.125
|
@@ -52,7 +52,7 @@ describe Prawn::SVG::Calculators::DocumentSizing do
|
|
52
52
|
expect(sizing.output_height).to eq 100
|
53
53
|
end
|
54
54
|
|
55
|
-
it
|
55
|
+
it 'scales again based on requested height' do
|
56
56
|
sizing.requested_height = 100
|
57
57
|
sizing.calculate
|
58
58
|
expect(sizing.x_scale).to eq 0.125
|
@@ -63,18 +63,18 @@ describe Prawn::SVG::Calculators::DocumentSizing do
|
|
63
63
|
expect(sizing.output_height).to eq 100
|
64
64
|
end
|
65
65
|
|
66
|
-
it
|
67
|
-
sizing.document_width = sizing.document_height =
|
66
|
+
it 'correctly handles % values being passed in' do
|
67
|
+
sizing.document_width = sizing.document_height = '50%'
|
68
68
|
sizing.calculate
|
69
69
|
expect(sizing.output_width).to eq 600
|
70
70
|
expect(sizing.output_height).to eq 400
|
71
71
|
end
|
72
72
|
|
73
|
-
context
|
74
|
-
context
|
75
|
-
let(:attributes) { {
|
73
|
+
context 'when SVG does not specify width and height' do
|
74
|
+
context 'when a viewBox is specified' do
|
75
|
+
let(:attributes) { { 'viewBox' => '0 0 100 200' } }
|
76
76
|
|
77
|
-
it
|
77
|
+
it 'defaults to 100% width and uses the viewbox ratio for height' do
|
78
78
|
sizing.calculate
|
79
79
|
expect(sizing.viewport_width).to eq 100
|
80
80
|
expect(sizing.viewport_height).to eq 200
|
@@ -83,10 +83,10 @@ describe Prawn::SVG::Calculators::DocumentSizing do
|
|
83
83
|
end
|
84
84
|
end
|
85
85
|
|
86
|
-
context
|
86
|
+
context 'when a requested width and height are supplied' do
|
87
87
|
let(:attributes) { {} }
|
88
88
|
|
89
|
-
it
|
89
|
+
it 'uses the requested width and height' do
|
90
90
|
sizing.requested_width = 550
|
91
91
|
sizing.requested_height = 400
|
92
92
|
sizing.calculate
|
@@ -98,10 +98,10 @@ describe Prawn::SVG::Calculators::DocumentSizing do
|
|
98
98
|
end
|
99
99
|
end
|
100
100
|
|
101
|
-
context
|
102
|
-
let(:attributes) { {
|
101
|
+
context 'when a viewBox and a requested width/height are supplied' do
|
102
|
+
let(:attributes) { { 'viewBox' => '0 0 100 200' } }
|
103
103
|
|
104
|
-
it
|
104
|
+
it 'uses the requested width and height' do
|
105
105
|
sizing.requested_width = 550
|
106
106
|
sizing.requested_height = 400
|
107
107
|
sizing.calculate
|
@@ -113,10 +113,10 @@ describe Prawn::SVG::Calculators::DocumentSizing do
|
|
113
113
|
end
|
114
114
|
end
|
115
115
|
|
116
|
-
context
|
117
|
-
let(:attributes) { {
|
116
|
+
context 'when a viewBox and a requested width is supplied' do
|
117
|
+
let(:attributes) { { 'viewBox' => '0 0 100 200' } }
|
118
118
|
|
119
|
-
it
|
119
|
+
it 'uses the requested width and calculates the height based on the viewBox' do
|
120
120
|
sizing.requested_width = 550
|
121
121
|
sizing.calculate
|
122
122
|
|
@@ -127,10 +127,10 @@ describe Prawn::SVG::Calculators::DocumentSizing do
|
|
127
127
|
end
|
128
128
|
end
|
129
129
|
|
130
|
-
context
|
131
|
-
let(:attributes) { {
|
130
|
+
context 'when a viewBox and a requested height is supplied' do
|
131
|
+
let(:attributes) { { 'viewBox' => '0 0 100 200' } }
|
132
132
|
|
133
|
-
it
|
133
|
+
it 'uses the requested height and calculates the width based on the viewBox' do
|
134
134
|
sizing.requested_height = 400
|
135
135
|
sizing.calculate
|
136
136
|
|
@@ -141,10 +141,10 @@ describe Prawn::SVG::Calculators::DocumentSizing do
|
|
141
141
|
end
|
142
142
|
end
|
143
143
|
|
144
|
-
context
|
144
|
+
context 'when neither viewBox nor requested width/height specified' do
|
145
145
|
let(:attributes) { {} }
|
146
146
|
|
147
|
-
it
|
147
|
+
it 'defaults to 100%' do
|
148
148
|
sizing.calculate
|
149
149
|
|
150
150
|
expect(sizing.output_width).to eq 1200
|
@@ -12,7 +12,8 @@ describe Prawn::SVG::Calculators::Pixels do
|
|
12
12
|
end
|
13
13
|
|
14
14
|
let(:viewport_sizing) do
|
15
|
-
instance_double(Prawn::SVG::Calculators::DocumentSizing, viewport_width: 600, viewport_height: 400,
|
15
|
+
instance_double(Prawn::SVG::Calculators::DocumentSizing, viewport_width: 600, viewport_height: 400,
|
16
|
+
viewport_diagonal: 500, :requested_width= => nil, :requested_height= => nil)
|
16
17
|
end
|
17
18
|
|
18
19
|
let(:document_sizing) do
|
@@ -29,49 +30,49 @@ describe Prawn::SVG::Calculators::Pixels do
|
|
29
30
|
allow(subject).to receive(:document).and_return(document)
|
30
31
|
end
|
31
32
|
|
32
|
-
describe
|
33
|
-
it
|
33
|
+
describe '#pixels' do
|
34
|
+
it 'converts a variety of measurement units to points' do
|
34
35
|
expect(subject.pixels(32)).to eq 32.0
|
35
36
|
expect(subject.pixels(32.0)).to eq 32.0
|
36
|
-
expect(subject.pixels(
|
37
|
-
expect(subject.pixels(
|
38
|
-
expect(subject.pixels(
|
39
|
-
expect(subject.pixels(
|
40
|
-
expect(subject.pixels(
|
41
|
-
expect(subject.pixels(
|
42
|
-
expect(subject.pixels(
|
43
|
-
expect(subject.pixels(
|
44
|
-
expect(subject.pixels(
|
45
|
-
expect(subject.pixels(
|
46
|
-
expect(subject.pixels(
|
37
|
+
expect(subject.pixels('32')).to eq 32.0
|
38
|
+
expect(subject.pixels('32unknown')).to eq 32.0
|
39
|
+
expect(subject.pixels('32px')).to eq 32.0
|
40
|
+
expect(subject.pixels('32pt')).to eq 32.0
|
41
|
+
expect(subject.pixels('32in')).to eq 32.0 * 72
|
42
|
+
expect(subject.pixels('32pc')).to eq 32.0 * 15
|
43
|
+
expect(subject.pixels('4em')).to eq 4 * 16
|
44
|
+
expect(subject.pixels('4ex')).to eq 4 * 8
|
45
|
+
expect(subject.pixels('32mm')).to be_within(0.0001).of(32 * 72 * 0.0393700787)
|
46
|
+
expect(subject.pixels('32cm')).to be_within(0.0001).of(32 * 72 * 0.393700787)
|
47
|
+
expect(subject.pixels('50%')).to eq 250
|
47
48
|
end
|
48
49
|
end
|
49
50
|
|
50
|
-
describe
|
51
|
-
it
|
52
|
-
expect(subject.x_pixels(
|
53
|
-
expect(subject.x_pixels(
|
51
|
+
describe '#x_pixels' do
|
52
|
+
it 'uses the viewport width for percentages' do
|
53
|
+
expect(subject.x_pixels('50')).to eq 50
|
54
|
+
expect(subject.x_pixels('50%')).to eq 300
|
54
55
|
end
|
55
56
|
end
|
56
57
|
|
57
|
-
describe
|
58
|
-
it
|
59
|
-
expect(subject.y_pixels(
|
60
|
-
expect(subject.y_pixels(
|
58
|
+
describe '#y_pixels' do
|
59
|
+
it 'uses the viewport height for percentages' do
|
60
|
+
expect(subject.y_pixels('50')).to eq 50
|
61
|
+
expect(subject.y_pixels('50%')).to eq 200
|
61
62
|
end
|
62
63
|
end
|
63
64
|
|
64
|
-
describe
|
65
|
-
it
|
66
|
-
expect(subject.x(
|
67
|
-
expect(subject.x(
|
65
|
+
describe '#x' do
|
66
|
+
it 'performs the same as #x_pixels' do
|
67
|
+
expect(subject.x('50')).to eq 50
|
68
|
+
expect(subject.x('50%')).to eq 300
|
68
69
|
end
|
69
70
|
end
|
70
71
|
|
71
|
-
describe
|
72
|
-
it
|
73
|
-
expect(subject.y(
|
74
|
-
expect(subject.y(
|
72
|
+
describe '#y' do
|
73
|
+
it 'performs the same as #y_pixels but subtracts the pixels from the page height' do
|
74
|
+
expect(subject.y('50')).to eq 800 - 50
|
75
|
+
expect(subject.y('50%')).to eq 800 - 200
|
75
76
|
end
|
76
77
|
end
|
77
78
|
end
|
@@ -1,70 +1,70 @@
|
|
1
|
-
require File.dirname(__FILE__)
|
1
|
+
require "#{File.dirname(__FILE__)}/../../spec_helper"
|
2
2
|
|
3
3
|
describe Prawn::SVG::Color do
|
4
|
-
describe
|
5
|
-
it
|
6
|
-
Prawn::SVG::Color.css_color_to_prawn_color(
|
4
|
+
describe '::css_color_to_prawn_color' do
|
5
|
+
it 'converts #xxx to a hex value' do
|
6
|
+
Prawn::SVG::Color.css_color_to_prawn_color('#9ab').should == '99aabb'
|
7
7
|
end
|
8
8
|
|
9
|
-
it
|
10
|
-
Prawn::SVG::Color.css_color_to_prawn_color(
|
9
|
+
it 'converts #xxxxxx to a hex value' do
|
10
|
+
Prawn::SVG::Color.css_color_to_prawn_color('#9ab123').should == '9ab123'
|
11
11
|
end
|
12
12
|
|
13
|
-
it
|
14
|
-
Prawn::SVG::Color.css_color_to_prawn_color(
|
13
|
+
it 'converts an html colour name to a hex value' do
|
14
|
+
Prawn::SVG::Color.css_color_to_prawn_color('White').should == 'ffffff'
|
15
15
|
end
|
16
16
|
|
17
|
-
it
|
18
|
-
Prawn::SVG::Color.css_color_to_prawn_color(
|
19
|
-
Prawn::SVG::Color.css_color_to_prawn_color(
|
17
|
+
it 'converts an rgb string to a hex value' do
|
18
|
+
Prawn::SVG::Color.css_color_to_prawn_color('rgb(16, 32, 48)').should
|
19
|
+
Prawn::SVG::Color.css_color_to_prawn_color('rgb(-5, 50%, 120%)').should == '007fff'
|
20
20
|
end
|
21
21
|
|
22
|
-
it
|
23
|
-
expect(Prawn::SVG::Color.css_color_to_prawn_color(
|
24
|
-
expect(Prawn::SVG::Color.css_color_to_prawn_color(
|
22
|
+
it 'converts a CMYK string to an array of numbers' do
|
23
|
+
expect(Prawn::SVG::Color.css_color_to_prawn_color('device-cmyk(0, 0.32, 0.48, 1)')).to eq [0, 32, 48, 100]
|
24
|
+
expect(Prawn::SVG::Color.css_color_to_prawn_color('device-cmyk(-5, 50%, 120%, -5%)')).to eq [0, 50, 100, 0]
|
25
25
|
end
|
26
26
|
|
27
|
-
it
|
28
|
-
Prawn::SVG::Color.css_color_to_prawn_color(
|
27
|
+
it 'scans the string and finds the first colour it can parse' do
|
28
|
+
Prawn::SVG::Color.css_color_to_prawn_color('function(#someurl, 0) nonexistent rgb( 3 ,4,5 ) white').should == '030405'
|
29
29
|
end
|
30
30
|
|
31
|
-
it
|
32
|
-
expect(Prawn::SVG::Color.css_color_to_prawn_color(
|
31
|
+
it 'ignores url()s' do
|
32
|
+
expect(Prawn::SVG::Color.css_color_to_prawn_color('url(#someplace) red')).to eq 'ff0000'
|
33
33
|
end
|
34
34
|
|
35
35
|
it "returns black if the color doesn't exist" do
|
36
|
-
expect(Prawn::SVG::Color.css_color_to_prawn_color(
|
36
|
+
expect(Prawn::SVG::Color.css_color_to_prawn_color('blurble')).to eq '000000'
|
37
37
|
end
|
38
38
|
|
39
39
|
it "returns nil if there's no fallback after a url()" do
|
40
|
-
expect(Prawn::SVG::Color.css_color_to_prawn_color(
|
40
|
+
expect(Prawn::SVG::Color.css_color_to_prawn_color('url(#someplace)')).to be nil
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
44
|
-
describe
|
45
|
-
let(:gradients) { {
|
44
|
+
describe '::parse' do
|
45
|
+
let(:gradients) { { 'flan' => flan_gradient, 'drob' => drob_gradient } }
|
46
46
|
let(:flan_gradient) { double }
|
47
47
|
let(:drob_gradient) { double }
|
48
48
|
|
49
|
-
it
|
50
|
-
results = Prawn::SVG::Color.parse(
|
49
|
+
it 'returns a list of all colors parsed, ignoring impossible or non-existent colors' do
|
50
|
+
results = Prawn::SVG::Color.parse('url(#nope) url(#flan) blurble green #123', gradients, :rgb)
|
51
51
|
expect(results).to eq [
|
52
52
|
flan_gradient,
|
53
|
-
Prawn::SVG::Color::RGB.new(
|
54
|
-
Prawn::SVG::Color::RGB.new(
|
53
|
+
Prawn::SVG::Color::RGB.new('008000'),
|
54
|
+
Prawn::SVG::Color::RGB.new('112233')
|
55
55
|
]
|
56
56
|
end
|
57
57
|
|
58
58
|
it "appends black to the list if there aren't any url() references" do
|
59
|
-
results = Prawn::SVG::Color.parse(
|
59
|
+
results = Prawn::SVG::Color.parse('blurble green', gradients, :rgb)
|
60
60
|
expect(results).to eq [
|
61
|
-
Prawn::SVG::Color::RGB.new(
|
62
|
-
Prawn::SVG::Color::RGB.new(
|
61
|
+
Prawn::SVG::Color::RGB.new('008000'),
|
62
|
+
Prawn::SVG::Color::RGB.new('000000')
|
63
63
|
]
|
64
64
|
end
|
65
65
|
|
66
|
-
it
|
67
|
-
results = Prawn::SVG::Color.parse(
|
66
|
+
it 'works in CMYK color mode' do
|
67
|
+
results = Prawn::SVG::Color.parse('blurble green', gradients, :cmyk)
|
68
68
|
expect(results).to eq [
|
69
69
|
Prawn::SVG::Color::CMYK.new([100, 0, 100, 50]),
|
70
70
|
Prawn::SVG::Color::CMYK.new([0, 0, 0, 100])
|
@@ -1,19 +1,19 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
RSpec.describe Prawn::SVG::CSS::FontFamilyParser do
|
4
|
-
describe
|
5
|
-
it
|
4
|
+
describe '#parse' do
|
5
|
+
it 'correctly handles quotes and escaping' do
|
6
6
|
tests = {
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
"'font name', other font"
|
11
|
-
"'font, name', other font" => [
|
12
|
-
'"font name", other font'
|
13
|
-
'"font, name", other font' => [
|
14
|
-
'weird \\" name'
|
15
|
-
'weird\\, name'
|
16
|
-
' stupid , spacing '
|
7
|
+
'' => [],
|
8
|
+
'font' => ['font'],
|
9
|
+
'font name, other font' => ['font name', 'other font'],
|
10
|
+
"'font name', other font" => ['font name', 'other font'],
|
11
|
+
"'font, name', other font" => ['font, name', 'other font'],
|
12
|
+
'"font name", other font' => ['font name', 'other font'],
|
13
|
+
'"font, name", other font' => ['font, name', 'other font'],
|
14
|
+
'weird \\" name' => ['weird " name'],
|
15
|
+
'weird\\, name' => ['weird, name'],
|
16
|
+
' stupid , spacing ' => ['stupid', 'spacing']
|
17
17
|
}
|
18
18
|
|
19
19
|
tests.each do |string, expected|
|
@@ -1,33 +1,33 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
RSpec.describe Prawn::SVG::CSS::SelectorParser do
|
4
|
-
describe
|
5
|
-
it
|
6
|
-
expect(described_class.parse(
|
7
|
-
expect(described_class.parse(
|
4
|
+
describe '::parse' do
|
5
|
+
it 'parses a simple selector' do
|
6
|
+
expect(described_class.parse('div')).to eq [{ name: 'div' }]
|
7
|
+
expect(described_class.parse('.c1')).to eq [{ class: ['c1'] }]
|
8
8
|
end
|
9
9
|
|
10
|
-
it
|
11
|
-
result = described_class.parse(
|
10
|
+
it 'parses a complex selector' do
|
11
|
+
result = described_class.parse('div#count .c1.c2 > span.large + div~.other:first-child *:nth-child(3)')
|
12
12
|
expect(result).to eq [
|
13
|
-
{name:
|
14
|
-
{combinator: :descendant, class: [
|
15
|
-
{combinator: :child, name:
|
16
|
-
{combinator: :adjacent, name:
|
17
|
-
{combinator: :siblings, class: [
|
18
|
-
{combinator: :descendant, name:
|
13
|
+
{ name: 'div', id: ['count'] },
|
14
|
+
{ combinator: :descendant, class: ['c1', 'c2'] },
|
15
|
+
{ combinator: :child, name: 'span', class: ['large'] },
|
16
|
+
{ combinator: :adjacent, name: 'div' },
|
17
|
+
{ combinator: :siblings, class: ['other'], pseudo_class: ['first-child'] },
|
18
|
+
{ combinator: :descendant, name: '*', pseudo_class: ['nth-child(3)'] }
|
19
19
|
]
|
20
20
|
end
|
21
21
|
|
22
|
-
it
|
23
|
-
expect(described_class.parse(
|
24
|
-
expect(described_class.parse(
|
25
|
-
expect(described_class.parse(
|
26
|
-
expect(described_class.parse(
|
27
|
-
expect(described_class.parse("[abc^='123']")).to eq [{attribute: [[
|
28
|
-
expect(described_class.parse("[abc^= '123' ]")).to eq [{attribute: [[
|
29
|
-
expect(described_class.parse("[abc^= '123\\'456' ]")).to eq [{attribute: [[
|
30
|
-
expect(described_class.parse('[abc^= "123\\"456" ]')).to eq [{attribute: [[
|
22
|
+
it 'parses attributes' do
|
23
|
+
expect(described_class.parse('[abc]')).to eq [{ attribute: [['abc', nil, nil]] }]
|
24
|
+
expect(described_class.parse('[abc=123]')).to eq [{ attribute: [['abc', '=', '123']] }]
|
25
|
+
expect(described_class.parse('[abc^=123]')).to eq [{ attribute: [['abc', '^=', '123']] }]
|
26
|
+
expect(described_class.parse('[ abc ^= 123 ]')).to eq [{ attribute: [['abc', '^=', '123']] }]
|
27
|
+
expect(described_class.parse("[abc^='123']")).to eq [{ attribute: [['abc', '^=', '123']] }]
|
28
|
+
expect(described_class.parse("[abc^= '123' ]")).to eq [{ attribute: [['abc', '^=', '123']] }]
|
29
|
+
expect(described_class.parse("[abc^= '123\\'456' ]")).to eq [{ attribute: [['abc', '^=', '123\'456']] }]
|
30
|
+
expect(described_class.parse('[abc^= "123\\"456" ]')).to eq [{ attribute: [['abc', '^=', '123"456']] }]
|
31
31
|
end
|
32
32
|
end
|
33
33
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
RSpec.describe Prawn::SVG::CSS::Stylesheets do
|
4
|
-
describe
|
4
|
+
describe 'typical usage' do
|
5
5
|
let(:svg) { <<-SVG }
|
6
6
|
<svg>
|
7
7
|
<style>
|
@@ -57,67 +57,73 @@ RSpec.describe Prawn::SVG::CSS::Stylesheets do
|
|
57
57
|
</svg>
|
58
58
|
SVG
|
59
59
|
|
60
|
-
it
|
60
|
+
it 'associates styles with elements' do
|
61
61
|
result = Prawn::SVG::CSS::Stylesheets.new(CssParser::Parser.new, REXML::Document.new(svg)).load
|
62
|
-
width_and_styles = result.map { |k, v| [k.attributes[
|
62
|
+
width_and_styles = result.map { |k, v| [k.attributes['width'].to_i, v] }.sort_by(&:first)
|
63
63
|
|
64
64
|
expected = [
|
65
|
-
[0, [[
|
66
|
-
[1, [[
|
67
|
-
[2,
|
68
|
-
|
69
|
-
|
65
|
+
[0, [['overflow', 'hidden', false]]],
|
66
|
+
[1, [['fill', '#ff0000', false]]],
|
67
|
+
[2,
|
68
|
+
[['fill', '#ff0000', false], ['fill', '#330000', false], ['fill', '#440000', false],
|
69
|
+
['fill', '#220000', false]]],
|
70
|
+
[3, [['fill', '#ff0000', false], ['fill', '#00ff00', false]]],
|
71
|
+
[4,
|
72
|
+
[['fill', '#ff0000', false], ['fill', '#330000', false], ['fill', '#440000', false],
|
73
|
+
['fill', '#00ff00', false]]]
|
70
74
|
]
|
71
75
|
|
72
|
-
expected << [5,
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
[
|
78
|
-
[
|
79
|
-
[
|
80
|
-
[
|
81
|
-
[
|
82
|
-
[
|
83
|
-
[
|
84
|
-
[
|
85
|
-
[
|
86
|
-
|
76
|
+
expected << [5,
|
77
|
+
[['fill', '#ff0000', false], ['fill', '#330000', false], ['fill', '#330000', false], ['fill', '#440000', false],
|
78
|
+
['fill', '#00ff00', false]]]
|
79
|
+
|
80
|
+
expected.push(
|
81
|
+
[6, [['fill', '#ff0000', false], ['fill', '#441234', false], ['fill', '#0000ff', false]]],
|
82
|
+
[7, [['fill', '#550000', false]]],
|
83
|
+
[8, [['fill', '#660000', false]]],
|
84
|
+
[9, [['fill', '#770000', false]]],
|
85
|
+
[10, [['fill', '#880000', false]]],
|
86
|
+
[11, [['fill', '#990000', false]]],
|
87
|
+
[12, [['fill', '#aa0000', false]]],
|
88
|
+
[13, [['fill', '#bb0000', false]]],
|
89
|
+
[14, [['fill', '#cc0000', false]]],
|
90
|
+
[15, [['fill', '#dd0000', false]]],
|
91
|
+
[16, [['fill', '#ee0000', false]]]
|
92
|
+
)
|
87
93
|
|
88
94
|
expect(width_and_styles).to eq(expected)
|
89
95
|
end
|
90
96
|
end
|
91
97
|
|
92
|
-
describe
|
98
|
+
describe 'style tag parsing' do
|
93
99
|
let(:svg) do
|
94
|
-
|
95
|
-
<svg>
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
z</style>
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
</svg>
|
100
|
+
<<~SVG
|
101
|
+
<svg>
|
102
|
+
<some-tag>
|
103
|
+
<style>a
|
104
|
+
before>
|
105
|
+
x <![CDATA[ y
|
106
|
+
inside <>>
|
107
|
+
k ]]> j
|
108
|
+
after
|
109
|
+
z</style>
|
110
|
+
</some-tag>
|
111
|
+
|
112
|
+
<other-tag>
|
113
|
+
<more-tag>
|
114
|
+
<style>hello</style>
|
115
|
+
</more-tag>
|
116
|
+
</other-tag>
|
117
|
+
</svg>
|
112
118
|
SVG
|
113
119
|
end
|
114
120
|
|
115
|
-
it
|
121
|
+
it 'scans the document for style tags and adds the style information to the css parser' do
|
116
122
|
css_parser = instance_double(CssParser::Parser)
|
117
123
|
|
118
|
-
expect(css_parser).to receive(:add_block!).with(
|
124
|
+
expect(css_parser).to receive(:add_block!).with('svg, symbol, image, marker, pattern, foreignObject { overflow: hidden }')
|
119
125
|
expect(css_parser).to receive(:add_block!).with("a\n before>\n x y\n inside <>>\n k j\n after\nz")
|
120
|
-
expect(css_parser).to receive(:add_block!).with(
|
126
|
+
expect(css_parser).to receive(:add_block!).with('hello')
|
121
127
|
allow(css_parser).to receive(:each_rule_set)
|
122
128
|
|
123
129
|
Prawn::SVG::CSS::Stylesheets.new(css_parser, REXML::Document.new(svg)).load
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Prawn::SVG::CSS::ValuesParser do
|
4
|
+
it 'parses specified values' do
|
5
|
+
values = 'hello world url("#myid") no-quote(very good) escaping(")\\")ok") rgb( 1,4, 5 )'
|
6
|
+
|
7
|
+
expect(described_class.parse(values)).to eq [
|
8
|
+
'hello',
|
9
|
+
'world',
|
10
|
+
['url', ['#myid']],
|
11
|
+
['no-quote', ['very good']],
|
12
|
+
['escaping', [')")ok']],
|
13
|
+
['rgb', %w[1 4 5]]
|
14
|
+
]
|
15
|
+
end
|
16
|
+
end
|