dragonfly_svg 0.0.4 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +7 -0
  3. data/README.md +17 -1
  4. data/dragonfly_svg.gemspec +18 -17
  5. data/lib/dragonfly_svg.rb +7 -0
  6. data/lib/dragonfly_svg/analysers/svg_properties.rb +22 -8
  7. data/lib/dragonfly_svg/plugin.rb +24 -25
  8. data/lib/dragonfly_svg/processors/extend_ids.rb +5 -2
  9. data/lib/dragonfly_svg/processors/remove_namespaces.rb +3 -3
  10. data/lib/dragonfly_svg/processors/set_attribute.rb +3 -2
  11. data/lib/dragonfly_svg/processors/set_dimensions.rb +2 -0
  12. data/lib/dragonfly_svg/processors/set_namespace.rb +3 -1
  13. data/lib/dragonfly_svg/processors/set_preserve_aspect_ratio.rb +2 -0
  14. data/lib/dragonfly_svg/processors/set_tag_value.rb +18 -0
  15. data/lib/dragonfly_svg/processors/set_view_box.rb +2 -0
  16. data/lib/dragonfly_svg/version.rb +1 -1
  17. data/samples/sample.svg +2 -1
  18. data/samples/sample_without_dimensions.svg +4 -0
  19. data/test/dragonfly_svg/analysers/svg_properties_test.rb +12 -25
  20. data/test/dragonfly_svg/plugin_test.rb +25 -96
  21. data/test/dragonfly_svg/processors/extend_ids_test.rb +18 -19
  22. data/test/dragonfly_svg/processors/remove_namespaces_test.rb +10 -11
  23. data/test/dragonfly_svg/processors/set_attribute_test.rb +14 -18
  24. data/test/dragonfly_svg/processors/set_dimensions_test.rb +10 -17
  25. data/test/dragonfly_svg/processors/set_namespace_test.rb +16 -15
  26. data/test/dragonfly_svg/processors/set_preserve_aspect_ratio_test.rb +16 -23
  27. data/test/dragonfly_svg/processors/set_tag_value_test.rb +20 -0
  28. data/test/dragonfly_svg/processors/set_view_box_test.rb +8 -13
  29. data/test/test_helper.rb +7 -9
  30. metadata +25 -13
  31. data/lib/dragonfly_svg/analysers/aspect_ratio_analyser.rb +0 -17
  32. data/lib/dragonfly_svg/analysers/base.rb +0 -11
  33. data/lib/dragonfly_svg/analysers/height_analyser.rb +0 -16
  34. data/lib/dragonfly_svg/analysers/landscape_analyser.rb +0 -17
  35. data/lib/dragonfly_svg/analysers/portrait_analyser.rb +0 -17
  36. data/lib/dragonfly_svg/analysers/width_analyser.rb +0 -16
  37. data/samples/sample.png +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 0a80f5be599ee36aeef6e1fb8b3ac547eacfa5dd
4
- data.tar.gz: 3381778fb2df92c6c806404a39f8e873aee38193
2
+ SHA256:
3
+ metadata.gz: 92bc94aeb68fd9cc8fbf967c27b7ace7a7778472a6c641462fa67cf7b9f74f6d
4
+ data.tar.gz: deb2869aba9c2fc76f5400df0783cc971f6a7b56cabed5ffe3aebdb819bad8ab
5
5
  SHA512:
6
- metadata.gz: daa3efc319ebe8457c22f460f1cf69e00c6bd8b9f270d98983d7d5d927b6d36c12dedf183ffe8f7d93c98014880bd0a795b7694ba98291a0c55a8ba1b48648fb
7
- data.tar.gz: bb23dfbe0b3f524e276962fe851bb95a8712fb442c7164df77d761d6baac63b7bf39af1595804a239cc2c14ac4422d94ecfe366eaca0f5d0c2e8c9d8d8afbbcb
6
+ metadata.gz: 165deab9c210352a43e7972ec5f44f4a54cfde88bf10d68f98129340c1015243eb4a31dfbdf869aef9a5fb192660210af427c7371e3209522f994c9e7d5ed18e
7
+ data.tar.gz: 50a51b640787b72c1b9badd203183494c629dce7fcffb217c4b5fa95b2db682ce96214b12768fb774d43d87e9a9b85e08a697a4b93b2eb934345743457822b29
@@ -0,0 +1,7 @@
1
+ # CHANGELOG
2
+
3
+ ## 1.0.0
4
+
5
+ * add `SUPPORTED_FORMATS` and raise errors when formats are not matching
6
+ * `svg_properties` analyser now fallbacks to `viewBox` values when `width` and `height` attributes not found
7
+ * add `set_tag_value` processor
data/README.md CHANGED
@@ -20,7 +20,7 @@ Or install it yourself as:
20
20
 
21
21
  $ gem install dragonfly_svg
22
22
 
23
- ## Plugin
23
+ ## Usage
24
24
  The analyser and processors are added by configuring the plugin
25
25
 
26
26
  ```ruby
@@ -29,6 +29,14 @@ Dragonfly.app.configure do
29
29
  end
30
30
  ```
31
31
 
32
+ ## Supported Formats
33
+
34
+ List of supported formats is available as:
35
+
36
+ ```ruby
37
+ DragonflySvg::SUPPORTED_FORMATS # => ["svg", "svgz", "svg.gz"]
38
+ ```
39
+
32
40
  ## Analyser
33
41
  The analyser supplies the following methods:
34
42
 
@@ -68,6 +76,14 @@ Allows to set attribute for specified `xpath`:
68
76
  svg.set_attribute('./*[name()="svg"]', 'style', 'margin: 50px;')
69
77
  ```
70
78
 
79
+ ### SetTagValue
80
+
81
+ Allows to set tag value for specified `xpath`:
82
+
83
+ ```ruby
84
+ svg.set_tag_value('./*[name()="text"]', 'Updated text')
85
+ ```
86
+
71
87
  ### SetDimensions
72
88
 
73
89
  Sets the dimensions of the SVG. Takes two parameters: `width` and `height`
@@ -1,29 +1,30 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
1
+
2
+ lib = File.expand_path('lib', __dir__)
3
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
  require 'dragonfly_svg/version'
5
5
 
6
6
  Gem::Specification.new do |spec|
7
- spec.name = "dragonfly_svg"
7
+ spec.name = 'dragonfly_svg'
8
8
  spec.version = DragonflySvg::VERSION
9
- spec.authors = ["Tomas Celizna"]
10
- spec.email = ["tomas.celizna@gmail.com"]
11
- spec.summary = %q{Dragonfly analyser and processor for SVGs.}
12
- spec.description = %q{Dragonfly analyser and processor for SVGs.}
13
- spec.homepage = "https://github.com/tomasc/dragonfly_svg"
14
- spec.license = "MIT"
9
+ spec.authors = ['Tomas Celizna']
10
+ spec.email = ['tomas.celizna@gmail.com']
11
+ spec.summary = 'Dragonfly analyser and processor for SVGs.'
12
+ spec.description = 'Dragonfly analyser and processor for SVGs.'
13
+ spec.homepage = 'https://github.com/tomasc/dragonfly_svg'
14
+ spec.license = 'MIT'
15
15
 
16
16
  spec.files = `git ls-files -z`.split("\x0")
17
17
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
- spec.require_paths = ["lib"]
19
+ spec.require_paths = ['lib']
20
20
 
21
- spec.add_dependency "dragonfly", "~> 1.0"
22
- spec.add_dependency "nokogiri"
21
+ spec.add_dependency 'dragonfly', '~> 1.0'
22
+ spec.add_dependency 'nokogiri'
23
23
 
24
- spec.add_development_dependency "bundler", "~> 1.6"
25
- spec.add_development_dependency "rake"
26
- spec.add_development_dependency "guard"
27
- spec.add_development_dependency "guard-minitest"
28
- spec.add_development_dependency "minitest"
24
+ spec.add_development_dependency 'bundler', '~> 1.6'
25
+ spec.add_development_dependency 'rake', '~> 10.4'
26
+ spec.add_development_dependency 'guard'
27
+ spec.add_development_dependency 'guard-minitest'
28
+ spec.add_development_dependency 'minitest'
29
+ spec.add_development_dependency 'minitest-reporters'
29
30
  end
@@ -1,3 +1,10 @@
1
1
  require 'dragonfly'
2
2
  require 'dragonfly_svg/plugin'
3
3
  require 'dragonfly_svg/version'
4
+
5
+ module DragonflySvg
6
+ class UnsupportedFormat < RuntimeError; end
7
+ class UnsupportedOutputFormat < RuntimeError; end
8
+
9
+ SUPPORTED_FORMATS = %w[svg svgz svg.gz]
10
+ end
@@ -4,20 +4,34 @@ module DragonflySvg
4
4
  module Analysers
5
5
  class SvgProperties
6
6
  def call(content)
7
- node = svg_node(content)
7
+ return {} unless SUPPORTED_FORMATS.include?(content.ext)
8
+ return {} unless doc = Nokogiri::XML(content.data)
9
+ return {} unless node = doc.xpath("//*[name()='svg']").first
8
10
 
9
11
  {
10
- width: node.get_attribute('width').to_f,
11
- height: node.get_attribute('height').to_f,
12
- id: node.get_attribute('id')
12
+ 'format' => content.ext.to_s,
13
+ 'width' => width(node).to_f,
14
+ 'height' => height(node).to_f,
15
+ 'id' => id(node)
13
16
  }
14
17
  end
15
18
 
16
- private # =============================================================
19
+ private
17
20
 
18
- def svg_node(content)
19
- return unless doc = Nokogiri::XML(content.data)
20
- doc.xpath("//*[name()='svg']").first
21
+ def viewBox(node)
22
+ node.get_attribute('viewBox').to_s.split(/\s+/)
23
+ end
24
+
25
+ def width(node)
26
+ node.get_attribute('width') || viewBox(node)[2]
27
+ end
28
+
29
+ def height(node)
30
+ node.get_attribute('height') || viewBox(node)[3]
31
+ end
32
+
33
+ def id(node)
34
+ node.get_attribute('id')
21
35
  end
22
36
  end
23
37
  end
@@ -1,11 +1,4 @@
1
- require 'dragonfly_svg/analysers/base'
2
-
3
- require 'dragonfly_svg/analysers/aspect_ratio_analyser'
4
- require 'dragonfly_svg/analysers/height_analyser'
5
- require 'dragonfly_svg/analysers/landscape_analyser'
6
- require 'dragonfly_svg/analysers/portrait_analyser'
7
1
  require 'dragonfly_svg/analysers/svg_properties'
8
- require 'dragonfly_svg/analysers/width_analyser'
9
2
 
10
3
  require 'dragonfly_svg/processors/extend_ids'
11
4
  require 'dragonfly_svg/processors/remove_namespaces'
@@ -13,34 +6,40 @@ require 'dragonfly_svg/processors/set_attribute'
13
6
  require 'dragonfly_svg/processors/set_dimensions'
14
7
  require 'dragonfly_svg/processors/set_namespace'
15
8
  require 'dragonfly_svg/processors/set_preserve_aspect_ratio'
9
+ require 'dragonfly_svg/processors/set_tag_value'
16
10
  require 'dragonfly_svg/processors/set_view_box'
17
11
 
18
12
  module DragonflySvg
19
13
  class Plugin
20
- def call(app, _opts = {})
21
- app.add_analyser :svg_properties, DragonflySvg::Analysers::SvgProperties.new
22
-
23
- DragonflySvg::Analysers::WidthAnalyser.new(app)
24
- DragonflySvg::Analysers::HeightAnalyser.new(app)
25
- DragonflySvg::Analysers::AspectRatioAnalyser.new(app)
26
- DragonflySvg::Analysers::PortraitAnalyser.new(app)
27
- DragonflySvg::Analysers::LandscapeAnalyser.new(app)
28
-
29
- app.add_analyser :id do |content|
30
- content.analyse(:svg_properties)[:id]
14
+ def call(app, options = {})
15
+ # Analysers
16
+ app.add_analyser :svg_properties, Analysers::SvgProperties.new
17
+
18
+ %w[ format
19
+ width
20
+ height
21
+ id
22
+ ].each do |name|
23
+ app.add_analyser(name) { |c| c.analyse(:svg_properties)[name] }
31
24
  end
32
25
 
26
+ app.add_analyser(:aspect_ratio) { |c| c.analyse(:width).to_f / c.analyse(:height).to_f }
27
+ app.add_analyser(:portrait) { |c| c.analyse(:aspect_ratio) < 1.0 }
28
+ app.add_analyser(:landscape) { |c| !c.analyse(:portrait) }
29
+
33
30
  # Aliases
34
31
  app.define(:portrait?) { portrait }
35
32
  app.define(:landscape?) { landscape }
36
33
 
37
- app.add_processor :extend_ids, DragonflySvg::Processors::ExtendIds.new
38
- app.add_processor :remove_namespaces, DragonflySvg::Processors::RemoveNamespaces.new
39
- app.add_processor :set_attribute, DragonflySvg::Processors::SetAttribute.new
40
- app.add_processor :set_dimensions, DragonflySvg::Processors::SetDimensions.new
41
- app.add_processor :set_namespace, DragonflySvg::Processors::SetNamespace.new
42
- app.add_processor :set_preserve_aspect_ratio, DragonflySvg::Processors::SetPreserveAspectRatio.new
43
- app.add_processor :set_view_box, DragonflySvg::Processors::SetViewBox.new
34
+ # Processors
35
+ app.add_processor :extend_ids, Processors::ExtendIds.new
36
+ app.add_processor :remove_namespaces, Processors::RemoveNamespaces.new
37
+ app.add_processor :set_attribute, Processors::SetAttribute.new
38
+ app.add_processor :set_dimensions, Processors::SetDimensions.new
39
+ app.add_processor :set_namespace, Processors::SetNamespace.new
40
+ app.add_processor :set_preserve_aspect_ratio, Processors::SetPreserveAspectRatio.new
41
+ app.add_processor :set_tag_value, Processors::SetTagValue.new
42
+ app.add_processor :set_view_box, Processors::SetViewBox.new
44
43
  end
45
44
  end
46
45
  end
@@ -1,9 +1,12 @@
1
1
  require 'nokogiri'
2
+ require 'securerandom'
2
3
 
3
4
  module DragonflySvg
4
5
  module Processors
5
6
  class ExtendIds
6
- def call(content, append_str = SecureRandom.urlsafe_base64(8))
7
+ def call(content, append_str = SecureRandom.urlsafe_base64(8), options = {})
8
+ raise UnsupportedFormat unless SUPPORTED_FORMATS.include?(content.ext)
9
+
7
10
  doc = Nokogiri::XML(content.data)
8
11
 
9
12
  # nodes with id attributes
@@ -18,7 +21,7 @@ module DragonflySvg
18
21
  node.set_attribute 'href', [node_href, append_str].join('-')
19
22
  end
20
23
 
21
- content.update(doc.to_xml)
24
+ content.update(doc.to_xml, 'name' => 'temp.svg')
22
25
  end
23
26
  end
24
27
  end
@@ -4,11 +4,11 @@ module DragonflySvg
4
4
  module Processors
5
5
  class RemoveNamespaces
6
6
  def call(content)
7
- doc = Nokogiri::XML(content.data)
7
+ raise UnsupportedFormat unless SUPPORTED_FORMATS.include?(content.ext)
8
8
 
9
+ doc = Nokogiri::XML(content.data)
9
10
  doc.remove_namespaces!
10
-
11
- content.update(doc.to_xml)
11
+ content.update(doc.to_xml, 'name' => 'temp.svg')
12
12
  end
13
13
  end
14
14
  end
@@ -4,13 +4,14 @@ module DragonflySvg
4
4
  module Processors
5
5
  class SetAttribute
6
6
  def call(content, xpath, attribute_name, value)
7
- doc = Nokogiri::XML(content.data)
7
+ raise UnsupportedFormat unless SUPPORTED_FORMATS.include?(content.ext)
8
8
 
9
+ doc = Nokogiri::XML(content.data)
9
10
  doc.xpath(xpath).each do |node|
10
11
  node.set_attribute attribute_name, value
11
12
  end
12
13
 
13
- content.update(doc.to_xml)
14
+ content.update(doc.to_xml, 'name' => 'temp.svg')
14
15
  end
15
16
  end
16
17
  end
@@ -4,6 +4,8 @@ module DragonflySvg
4
4
  module Processors
5
5
  class SetDimensions
6
6
  def call(content, width, height)
7
+ raise UnsupportedFormat unless SUPPORTED_FORMATS.include?(content.ext)
8
+
7
9
  SetAttribute.new.call(content, "//*[name()='svg']", 'width', width) if width
8
10
  SetAttribute.new.call(content, "//*[name()='svg']", 'height', height) if height
9
11
  end
@@ -4,6 +4,8 @@ module DragonflySvg
4
4
  module Processors
5
5
  class SetNamespace
6
6
  def call(content, namespace = 'http://www.w3.org/2000/svg')
7
+ raise UnsupportedFormat unless SUPPORTED_FORMATS.include?(content.ext)
8
+
7
9
  doc = Nokogiri::XML(content.data)
8
10
 
9
11
  if svg_node = doc.xpath("//*[name()='svg']").first
@@ -13,7 +15,7 @@ module DragonflySvg
13
15
  end
14
16
  end
15
17
 
16
- content.update(doc.to_xml)
18
+ content.update(doc.to_xml, 'name' => 'temp.svg')
17
19
  end
18
20
  end
19
21
  end
@@ -4,6 +4,8 @@ module DragonflySvg
4
4
  module Processors
5
5
  class SetPreserveAspectRatio
6
6
  def call(content, value = 'xMinYMin meet')
7
+ raise UnsupportedFormat unless SUPPORTED_FORMATS.include?(content.ext)
8
+
7
9
  SetAttribute.new.call(content, "//*[name()='svg']", 'preserveAspectRatio', value)
8
10
  end
9
11
  end
@@ -0,0 +1,18 @@
1
+ require 'nokogiri'
2
+
3
+ module DragonflySvg
4
+ module Processors
5
+ class SetTagValue
6
+ def call(content, xpath, value)
7
+ raise UnsupportedFormat unless SUPPORTED_FORMATS.include?(content.ext)
8
+
9
+ doc = Nokogiri::XML(content.data)
10
+ doc.xpath(xpath).each do |node|
11
+ node.inner_html = value
12
+ end
13
+
14
+ content.update(doc.to_xml, 'name' => 'temp.svg')
15
+ end
16
+ end
17
+ end
18
+ end
@@ -4,6 +4,8 @@ module DragonflySvg
4
4
  module Processors
5
5
  class SetViewBox
6
6
  def call(content, min_x, min_y, width, height)
7
+ raise UnsupportedFormat unless SUPPORTED_FORMATS.include?(content.ext)
8
+
7
9
  value = [min_x, min_y, width, height].map(&:to_s).join(' ')
8
10
  SetAttribute.new.call(content, "//*[name()='svg']", 'viewBox', value)
9
11
  end
@@ -1,3 +1,3 @@
1
1
  module DragonflySvg
2
- VERSION = '0.0.4'.freeze
2
+ VERSION = '1.0.0'.freeze
3
3
  end
@@ -1,4 +1,5 @@
1
1
  <?xml version="1.0"?>
2
2
  <svg version="1.1" id="sample_id" xmlns="http://www.w3.org/2000/svg" width="200" height="300" viewBox="0 0 200 300">
3
3
  <rect fill="none" stroke="#000000" x="0" y="0" width="200" height="300" />
4
- </svg>
4
+ <text>TEXT</text>
5
+ </svg>
@@ -0,0 +1,4 @@
1
+ <?xml version="1.0"?>
2
+ <svg version="1.1" id="sample_id" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 300">
3
+ <rect fill="none" stroke="#000000" x="0" y="0" width="200" height="300" />
4
+ </svg>
@@ -1,32 +1,19 @@
1
1
  require 'test_helper'
2
2
 
3
- module DragonflySvg
4
- module Analysers
5
- describe SvgProperties do
6
- let(:app) { test_app.configure_with(:svg) }
7
- let(:analyser) { DragonflySvg::Analysers::SvgProperties.new }
8
- let(:svg) { app.fetch_file(SAMPLES_DIR.join('sample.svg')) }
3
+ describe DragonflySvg::Analysers::SvgProperties do
4
+ let(:app) { test_app.configure_with(:svg) }
5
+ let(:analyser) { DragonflySvg::Analysers::SvgProperties.new }
6
+ let(:svg) { app.fetch_file(SAMPLES_DIR.join('sample.svg')) }
9
7
 
10
- describe 'call' do
11
- let(:svg_properties) { analyser.call(svg) }
12
- let(:ratio) { 200.0 / 300.0 }
8
+ it { analyser.call(svg).must_be_kind_of Hash }
9
+ it { analyser.call(svg)['width'].must_equal 200 }
10
+ it { analyser.call(svg)['height'].must_equal 300 }
11
+ it { analyser.call(svg)['id'].must_equal 'sample_id' }
13
12
 
14
- it 'returns Hash' do
15
- svg_properties.must_be_kind_of Hash
16
- end
13
+ describe 'when dimensions only in viewBox' do
14
+ let(:svg) { app.fetch_file(SAMPLES_DIR.join('sample_without_dimensions.svg')) }
17
15
 
18
- it ':width' do
19
- svg_properties[:width].must_equal 200
20
- end
21
-
22
- it ':height' do
23
- svg_properties[:height].must_equal 300
24
- end
25
-
26
- it ':id' do
27
- svg_properties[:id].must_equal 'sample_id'
28
- end
29
- end
30
- end
16
+ it { analyser.call(svg)['width'].must_equal 200 }
17
+ it { analyser.call(svg)['height'].must_equal 300 }
31
18
  end
32
19
  end
@@ -1,101 +1,30 @@
1
1
  require 'test_helper'
2
2
 
3
- module DragonflySvg
4
- describe Plugin do
5
- let(:app) { test_app.configure_with(:svg) }
6
- let(:svg) { app.fetch_file(SAMPLES_DIR.join('sample.svg')) }
7
-
8
- # ---------------------------------------------------------------------
9
-
10
- describe 'analysers' do
11
- it 'adds #svg_properties' do
12
- svg.must_respond_to :svg_properties
13
- end
14
-
15
- it 'adds #width' do
16
- svg.must_respond_to :width
17
- svg.width.must_equal 200.0
18
- end
19
-
20
- it 'adds #height' do
21
- svg.must_respond_to :height
22
- svg.height.must_equal 300.0
23
- end
24
-
25
- it 'adds #aspect_ratio' do
26
- svg.must_respond_to :aspect_ratio
27
- svg.aspect_ratio.must_equal 0.6666666666666666
28
- end
29
-
30
- it 'adds #portrait' do
31
- svg.must_respond_to :portrait
32
- svg.portrait.must_equal true
33
- end
34
-
35
- it 'adds #landscape' do
36
- svg.must_respond_to :landscape
37
- svg.landscape.must_equal false
38
- end
39
-
40
- it 'adds #id' do
41
- svg.must_respond_to :id
42
- end
43
-
44
- describe "when handling non svg files" do
45
- let(:png) { app.fetch_file(SAMPLES_DIR.join('sample.png')) }
46
-
47
- before do
48
- test_app.configure_with(:image_magick)
49
- end
50
-
51
- it 'still works to get the width' do
52
- png.width.must_equal 1
53
- end
54
-
55
- it 'still works to get the height' do
56
- png.height.must_equal 1
57
- end
58
-
59
- it 'still works to get the aspect ratio' do
60
- png.aspect_ratio.must_equal 1.0
61
- end
62
-
63
- it 'still works to ask for portrait' do
64
- png.portrait.must_equal true
65
- end
66
-
67
- it 'still works to ask for landscape' do
68
- png.landscape.must_equal false
69
- end
70
- end
71
- end
72
-
73
- # ---------------------------------------------------------------------
74
-
75
- describe 'processors' do
76
- it 'adds #extend_ids' do
77
- svg.must_respond_to :extend_ids
78
- end
79
-
80
- it 'adds #remove_namespaces' do
81
- svg.must_respond_to :remove_namespaces
82
- end
83
-
84
- it 'adds #set_dimensions' do
85
- svg.must_respond_to :set_dimensions
86
- end
87
-
88
- it 'adds #set_namespace' do
89
- svg.must_respond_to :set_namespace
90
- end
91
-
92
- it 'adds #set_preserve_aspect_ratio' do
93
- svg.must_respond_to :set_preserve_aspect_ratio
94
- end
3
+ describe DragonflySvg::Plugin do
4
+ let(:app) { test_app.configure_with(:svg) }
5
+ let(:content) { app.fetch_file(SAMPLES_DIR.join('sample.svg')) }
6
+
7
+ describe 'analysers' do
8
+ it { content.svg_properties.must_equal('format' => 'svg', 'width' => 200.0, 'height' => 300.0, 'id' => 'sample_id') }
9
+ it { content.format.must_equal 'svg' }
10
+ it { content.width.must_equal 200.0 }
11
+ it { content.height.must_equal 300.0 }
12
+ it { content.aspect_ratio.round(2).must_equal 0.67 }
13
+ it { content.must_be :portrait }
14
+ it { content.must_be :portrait? }
15
+ it { content.wont_be :landscape }
16
+ it { content.wont_be :landscape? }
17
+ it { content.id.must_equal 'sample_id' }
18
+ end
95
19
 
96
- it 'adds #set_view_box' do
97
- svg.must_respond_to :set_view_box
98
- end
99
- end
20
+ describe 'processors' do
21
+ it { content.must_respond_to :extend_ids }
22
+ it { content.must_respond_to :remove_namespaces }
23
+ it { content.must_respond_to :set_attribute }
24
+ it { content.must_respond_to :set_dimensions }
25
+ it { content.must_respond_to :set_namespace }
26
+ it { content.must_respond_to :set_preserve_aspect_ratio }
27
+ it { content.must_respond_to :set_tag_value }
28
+ it { content.must_respond_to :set_view_box }
100
29
  end
101
30
  end
@@ -1,26 +1,25 @@
1
1
  require 'test_helper'
2
2
 
3
- module DragonflySvg
4
- module Processors
5
- describe ExtendIds do
6
- let(:app) { test_app.configure_with(:svg) }
7
- let(:processor) { DragonflySvg::Processors::ExtendIds.new }
8
- let(:analyser) { DragonflySvg::Analysers::SvgProperties.new }
9
- let(:svg) { Dragonfly::Content.new(app, SAMPLES_DIR.join('sample.svg')) }
3
+ describe DragonflySvg::Processors::ExtendIds do
4
+ let(:app) { test_app.configure_with(:svg) }
5
+ let(:content) { Dragonfly::Content.new(app, SAMPLES_DIR.join('sample.svg')) }
6
+ let(:analyser) { DragonflySvg::Analysers::SvgProperties.new }
7
+ let(:processor) { DragonflySvg::Processors::ExtendIds.new }
10
8
 
11
- before do
12
- @orig_id = analyser.call(svg)[:id]
13
- end
9
+ before { @orig_id = analyser.call(content)['id'] }
14
10
 
15
- it 'adds unique ID' do
16
- processor.call(svg)
17
- analyser.call(svg)[:id].wont_equal @orig_id
18
- end
11
+ describe 'default' do
12
+ before { processor.call(content) }
13
+ it { analyser.call(content)['id'].wont_equal @orig_id }
14
+ end
15
+
16
+ describe 'supplied string' do
17
+ before { processor.call(content, 'foo') }
18
+ it { analyser.call(content)['id'].must_equal "#{@orig_id}-foo" }
19
+ end
19
20
 
20
- it 'adds supplied string to ID' do
21
- processor.call(svg, 'foo')
22
- analyser.call(svg)[:id].must_equal "#{@orig_id}-foo"
23
- end
24
- end
21
+ describe 'tempfile has extension' do
22
+ before { processor.call(content) }
23
+ it { content.tempfile.path.must_match /\.svg\z/ }
25
24
  end
26
25
  end
@@ -1,16 +1,15 @@
1
1
  require 'test_helper'
2
2
 
3
- module DragonflySvg
4
- module Processors
5
- describe RemoveNamespaces do
6
- let(:app) { test_app.configure_with(:svg) }
7
- let(:processor) { DragonflySvg::Processors::RemoveNamespaces.new }
8
- let(:svg) { Dragonfly::Content.new(app, SAMPLES_DIR.join('sample.svg')) }
3
+ describe DragonflySvg::Processors::RemoveNamespaces do
4
+ let(:app) { test_app.configure_with(:svg) }
5
+ let(:content) { Dragonfly::Content.new(app, SAMPLES_DIR.join('sample.svg')) }
6
+ let(:processor) { DragonflySvg::Processors::RemoveNamespaces.new }
9
7
 
10
- it 'removes namespaces' do
11
- processor.call(svg)
12
- svg.data.wont_include 'xmlns='
13
- end
14
- end
8
+ before { processor.call(content) }
9
+
10
+ it { content.data.wont_include 'xmlns=' }
11
+
12
+ describe 'tempfile has extension' do
13
+ it { content.tempfile.path.must_match /\.svg\z/ }
15
14
  end
16
15
  end
@@ -1,25 +1,21 @@
1
1
  require 'test_helper'
2
2
 
3
- module DragonflySvg
4
- module Processors
5
- describe SetAttribute do
6
- let(:app) { test_app.configure_with(:svg) }
7
- let(:processor) { DragonflySvg::Processors::SetAttribute.new }
8
- let(:analyser) { DragonflySvg::Analysers::SvgProperties.new }
9
- let(:svg) { Dragonfly::Content.new(app, SAMPLES_DIR.join('sample.svg')) }
3
+ describe DragonflySvg::Processors::SetAttribute do
4
+ let(:app) { test_app.configure_with(:svg) }
5
+ let(:processor) { DragonflySvg::Processors::SetAttribute.new }
6
+ let(:analyser) { DragonflySvg::Analysers::SvgProperties.new }
7
+ let(:content) { Dragonfly::Content.new(app, SAMPLES_DIR.join('sample.svg')) }
10
8
 
11
- let(:xpath) { "./*[name()='svg']" }
12
- let(:attribute_name) { 'style' }
13
- let(:attribute_value) { 'margin: 50px;' }
9
+ let(:xpath) { "./*[name()='svg']" }
10
+ let(:attribute_name) { 'style' }
11
+ let(:attribute_value) { 'margin: 50px;' }
14
12
 
15
- before do
16
- processor.call(svg, xpath, attribute_name, attribute_value)
17
- end
13
+ before { processor.call(content, xpath, attribute_name, attribute_value) }
18
14
 
19
- it 'sets attribute' do
20
- Nokogiri::XML(svg.data).xpath(xpath).count.must_equal 1
21
- Nokogiri::XML(svg.data).xpath(xpath).first.get_attribute('style').must_equal attribute_value
22
- end
23
- end
15
+ it { Nokogiri::XML(content.data).xpath(xpath).count.must_equal 1 }
16
+ it { Nokogiri::XML(content.data).xpath(xpath).first.get_attribute('style').must_equal attribute_value }
17
+
18
+ describe 'tempfile has extension' do
19
+ it { content.tempfile.path.must_match /\.svg\z/ }
24
20
  end
25
21
  end
@@ -1,24 +1,17 @@
1
1
  require 'test_helper'
2
2
 
3
- module DragonflySvg
4
- module Processors
5
- describe SetDimensions do
6
- let(:app) { test_app.configure_with(:svg) }
7
- let(:processor) { DragonflySvg::Processors::SetDimensions.new }
8
- let(:analyser) { DragonflySvg::Analysers::SvgProperties.new }
9
- let(:svg) { Dragonfly::Content.new(app, SAMPLES_DIR.join('sample.svg')) }
3
+ describe DragonflySvg::Processors::SetDimensions do
4
+ let(:app) { test_app.configure_with(:svg) }
5
+ let(:content) { Dragonfly::Content.new(app, SAMPLES_DIR.join('sample.svg')) }
6
+ let(:processor) { DragonflySvg::Processors::SetDimensions.new }
7
+ let(:analyser) { DragonflySvg::Analysers::SvgProperties.new }
10
8
 
11
- before do
12
- processor.call(svg, 400, 600)
13
- end
9
+ before { processor.call(content, 400, 600) }
14
10
 
15
- it 'sets width' do
16
- analyser.call(svg)[:width].must_equal 400
17
- end
11
+ it { analyser.call(content)['width'].must_equal 400 }
12
+ it { analyser.call(content)['height'].must_equal 600 }
18
13
 
19
- it 'sets height' do
20
- analyser.call(svg)[:height].must_equal 600
21
- end
22
- end
14
+ describe 'tempfile has extension' do
15
+ it { content.tempfile.path.must_match /\.svg\z/ }
23
16
  end
24
17
  end
@@ -1,21 +1,22 @@
1
1
  require 'test_helper'
2
2
 
3
- module DragonflySvg
4
- module Processors
5
- describe SetNamespace do
6
- let(:app) { test_app.configure_with(:svg) }
7
- let(:processor) { DragonflySvg::Processors::SetNamespace.new }
8
- let(:svg) { Dragonfly::Content.new(app, SAMPLES_DIR.join('sample.svg')) }
3
+ describe DragonflySvg::Processors::SetNamespace do
4
+ let(:app) { test_app.configure_with(:svg) }
5
+ let(:content) { Dragonfly::Content.new(app, SAMPLES_DIR.join('sample.svg')) }
6
+ let(:processor) { DragonflySvg::Processors::SetNamespace.new }
9
7
 
10
- it 'sets default namespace' do
11
- processor.call(svg)
12
- svg.data.must_include 'http://www.w3.org/2000/svg'
13
- end
8
+ describe 'by default' do
9
+ before { processor.call(content) }
10
+ it { content.data.must_include 'http://www.w3.org/2000/svg' }
11
+ end
12
+
13
+ describe 'custom namespace' do
14
+ before { processor.call(content, 'custom_namespace') }
15
+ it { content.data.must_include 'custom_namespace' }
16
+ end
14
17
 
15
- it 'sets custom namespace' do
16
- processor.call(svg, 'custom_namespace')
17
- svg.data.must_include 'custom_namespace'
18
- end
19
- end
18
+ describe 'tempfile has extension' do
19
+ before { processor.call(content) }
20
+ it { content.tempfile.path.must_match /\.svg\z/ }
20
21
  end
21
22
  end
@@ -1,30 +1,23 @@
1
1
  require 'test_helper'
2
2
 
3
- module DragonflySvg
4
- module Processors
5
- describe SetPreserveAspectRatio do
6
- let(:app) { test_app.configure_with(:svg) }
7
- let(:processor) { DragonflySvg::Processors::SetPreserveAspectRatio.new }
8
- let(:svg) { Dragonfly::Content.new(app, SAMPLES_DIR.join('sample.svg')) }
3
+ describe DragonflySvg::Processors::SetPreserveAspectRatio do
4
+ let(:app) { test_app.configure_with(:svg) }
5
+ let(:content) { Dragonfly::Content.new(app, SAMPLES_DIR.join('sample.svg')) }
6
+ let(:processor) { DragonflySvg::Processors::SetPreserveAspectRatio.new }
9
7
 
10
- describe 'with default value' do
11
- it 'adds preserveAspectRatio attribute' do
12
- processor.call(svg)
13
- svg.data.must_include 'preserveAspectRatio'
14
- end
8
+ describe 'with default value' do
9
+ before { processor.call(content) }
10
+ it { content.data.must_include 'preserveAspectRatio' }
11
+ it { content.data.must_include 'xMinYMin meet' }
12
+ end
15
13
 
16
- it 'sets default value' do
17
- processor.call(svg)
18
- svg.data.must_include 'xMinYMin meet'
19
- end
20
- end
14
+ describe 'with specified value' do
15
+ before { processor.call(content, 'xMidYMid meet') }
16
+ it { content.data.must_include 'xMidYMid meet' }
17
+ end
21
18
 
22
- describe 'with specified value' do
23
- it 'adds preserveAspectRatio with specified value' do
24
- processor.call(svg, 'xMidYMid meet')
25
- svg.data.must_include 'xMidYMid meet'
26
- end
27
- end
28
- end
19
+ describe 'tempfile has extension' do
20
+ before { processor.call(content) }
21
+ it { content.tempfile.path.must_match /\.svg\z/ }
29
22
  end
30
23
  end
@@ -0,0 +1,20 @@
1
+ require 'test_helper'
2
+
3
+ describe DragonflySvg::Processors::SetTagValue do
4
+ let(:app) { test_app.configure_with(:svg) }
5
+ let(:processor) { DragonflySvg::Processors::SetTagValue.new }
6
+ let(:analyser) { DragonflySvg::Analysers::SvgProperties.new }
7
+ let(:content) { Dragonfly::Content.new(app, SAMPLES_DIR.join('sample.svg')) }
8
+
9
+ let(:xpath) { "//*[name()='text']" }
10
+ let(:val) { 'TEST' }
11
+
12
+ before { processor.call(content, xpath, val) }
13
+
14
+ it { Nokogiri::XML(content.data).xpath(xpath).count.must_equal 1 }
15
+ it { Nokogiri::XML(content.data).xpath(xpath).first.inner_html.must_equal val }
16
+
17
+ describe 'tempfile has extension' do
18
+ it { content.tempfile.path.must_match /\.svg\z/ }
19
+ end
20
+ end
@@ -1,19 +1,14 @@
1
1
  require 'test_helper'
2
2
 
3
- module DragonflySvg
4
- module Processors
5
- describe SetViewBox do
6
- let(:app) { test_app.configure_with(:svg) }
7
- let(:processor) { DragonflySvg::Processors::SetViewBox.new }
8
- let(:svg) { Dragonfly::Content.new(app, SAMPLES_DIR.join('sample.svg')) }
3
+ describe DragonflySvg::Processors::SetViewBox do
4
+ let(:app) { test_app.configure_with(:svg) }
5
+ let(:content) { Dragonfly::Content.new(app, SAMPLES_DIR.join('sample.svg')) }
6
+ let(:processor) { DragonflySvg::Processors::SetViewBox.new }
9
7
 
10
- before do
11
- processor.call(svg, 0, 0, 400, 600)
12
- end
8
+ before { processor.call(content, 0, 0, 400, 600) }
9
+ it { content.data.must_include '0 0 400 600' }
13
10
 
14
- it 'sets view box' do
15
- svg.data.must_include '0 0 400 600'
16
- end
17
- end
11
+ describe 'tempfile has extension' do
12
+ it { content.tempfile.path.must_match /\.svg\z/ }
18
13
  end
19
14
  end
@@ -2,20 +2,18 @@ require 'bundler/setup'
2
2
 
3
3
  require 'minitest'
4
4
  require 'minitest/autorun'
5
+ require 'minitest/reporters'
5
6
  require 'minitest/spec'
6
7
 
7
- require 'dragonfly'
8
8
  require 'dragonfly_svg'
9
9
 
10
- # ---------------------------------------------------------------------
10
+ SAMPLES_DIR = Pathname.new(File.expand_path('../samples', __dir__))
11
11
 
12
- SAMPLES_DIR = Pathname.new(File.expand_path('../../samples', __FILE__))
13
-
14
- # ---------------------------------------------------------------------
12
+ Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new
15
13
 
16
14
  def test_app(name = nil)
17
- app = Dragonfly::App.instance(name)
18
- app.datastore = Dragonfly::MemoryDataStore.new
19
- app.secret = 'test secret'
20
- app
15
+ Dragonfly::App.instance(name).tap do |app|
16
+ app.datastore = Dragonfly::MemoryDataStore.new
17
+ app.secret = 'test secret'
18
+ end
21
19
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dragonfly_svg
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tomas Celizna
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-04-24 00:00:00.000000000 Z
11
+ date: 2018-07-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dragonfly
@@ -54,6 +54,20 @@ dependencies:
54
54
  version: '1.6'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '10.4'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '10.4'
69
+ - !ruby/object:Gem::Dependency
70
+ name: guard
57
71
  requirement: !ruby/object:Gem::Requirement
58
72
  requirements:
59
73
  - - ">="
@@ -67,7 +81,7 @@ dependencies:
67
81
  - !ruby/object:Gem::Version
68
82
  version: '0'
69
83
  - !ruby/object:Gem::Dependency
70
- name: guard
84
+ name: guard-minitest
71
85
  requirement: !ruby/object:Gem::Requirement
72
86
  requirements:
73
87
  - - ">="
@@ -81,7 +95,7 @@ dependencies:
81
95
  - !ruby/object:Gem::Version
82
96
  version: '0'
83
97
  - !ruby/object:Gem::Dependency
84
- name: guard-minitest
98
+ name: minitest
85
99
  requirement: !ruby/object:Gem::Requirement
86
100
  requirements:
87
101
  - - ">="
@@ -95,7 +109,7 @@ dependencies:
95
109
  - !ruby/object:Gem::Version
96
110
  version: '0'
97
111
  - !ruby/object:Gem::Dependency
98
- name: minitest
112
+ name: minitest-reporters
99
113
  requirement: !ruby/object:Gem::Requirement
100
114
  requirements:
101
115
  - - ">="
@@ -118,6 +132,7 @@ files:
118
132
  - ".coveralls.yml"
119
133
  - ".gitignore"
120
134
  - ".travis.yml"
135
+ - CHANGELOG.md
121
136
  - Gemfile
122
137
  - Guardfile
123
138
  - LICENSE
@@ -125,13 +140,7 @@ files:
125
140
  - Rakefile
126
141
  - dragonfly_svg.gemspec
127
142
  - lib/dragonfly_svg.rb
128
- - lib/dragonfly_svg/analysers/aspect_ratio_analyser.rb
129
- - lib/dragonfly_svg/analysers/base.rb
130
- - lib/dragonfly_svg/analysers/height_analyser.rb
131
- - lib/dragonfly_svg/analysers/landscape_analyser.rb
132
- - lib/dragonfly_svg/analysers/portrait_analyser.rb
133
143
  - lib/dragonfly_svg/analysers/svg_properties.rb
134
- - lib/dragonfly_svg/analysers/width_analyser.rb
135
144
  - lib/dragonfly_svg/plugin.rb
136
145
  - lib/dragonfly_svg/processors/extend_ids.rb
137
146
  - lib/dragonfly_svg/processors/remove_namespaces.rb
@@ -139,10 +148,11 @@ files:
139
148
  - lib/dragonfly_svg/processors/set_dimensions.rb
140
149
  - lib/dragonfly_svg/processors/set_namespace.rb
141
150
  - lib/dragonfly_svg/processors/set_preserve_aspect_ratio.rb
151
+ - lib/dragonfly_svg/processors/set_tag_value.rb
142
152
  - lib/dragonfly_svg/processors/set_view_box.rb
143
153
  - lib/dragonfly_svg/version.rb
144
- - samples/sample.png
145
154
  - samples/sample.svg
155
+ - samples/sample_without_dimensions.svg
146
156
  - test/dragonfly_svg/analysers/svg_properties_test.rb
147
157
  - test/dragonfly_svg/plugin_test.rb
148
158
  - test/dragonfly_svg/processors/extend_ids_test.rb
@@ -151,6 +161,7 @@ files:
151
161
  - test/dragonfly_svg/processors/set_dimensions_test.rb
152
162
  - test/dragonfly_svg/processors/set_namespace_test.rb
153
163
  - test/dragonfly_svg/processors/set_preserve_aspect_ratio_test.rb
164
+ - test/dragonfly_svg/processors/set_tag_value_test.rb
154
165
  - test/dragonfly_svg/processors/set_view_box_test.rb
155
166
  - test/test_helper.rb
156
167
  homepage: https://github.com/tomasc/dragonfly_svg
@@ -173,7 +184,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
173
184
  version: '0'
174
185
  requirements: []
175
186
  rubyforge_project:
176
- rubygems_version: 2.4.8
187
+ rubygems_version: 2.7.6
177
188
  signing_key:
178
189
  specification_version: 4
179
190
  summary: Dragonfly analyser and processor for SVGs.
@@ -186,5 +197,6 @@ test_files:
186
197
  - test/dragonfly_svg/processors/set_dimensions_test.rb
187
198
  - test/dragonfly_svg/processors/set_namespace_test.rb
188
199
  - test/dragonfly_svg/processors/set_preserve_aspect_ratio_test.rb
200
+ - test/dragonfly_svg/processors/set_tag_value_test.rb
189
201
  - test/dragonfly_svg/processors/set_view_box_test.rb
190
202
  - test/test_helper.rb
@@ -1,17 +0,0 @@
1
- module DragonflySvg
2
- module Analysers
3
- class AspectRatioAnalyser < Base
4
- def initialize(app)
5
- original = app.analysers.items[:aspect_ratio]
6
- app.add_analyser(:aspect_ratio) do |content|
7
- if is_svg?(content)
8
- attrs = content.analyse(:svg_properties)
9
- attrs[:width].to_f / attrs[:height]
10
- elsif original
11
- original.call(content)
12
- end
13
- end
14
- end
15
- end
16
- end
17
- end
@@ -1,11 +0,0 @@
1
- module DragonflySvg
2
- SVG_MIME_TYPE = 'image/svg+xml'.freeze
3
-
4
- module Analysers
5
- class Base
6
- def is_svg?(content)
7
- content.mime_type == DragonflySvg::SVG_MIME_TYPE
8
- end
9
- end
10
- end
11
- end
@@ -1,16 +0,0 @@
1
- module DragonflySvg
2
- module Analysers
3
- class HeightAnalyser < Base
4
- def initialize(app)
5
- original = app.analysers.items[:height]
6
- app.add_analyser(:height) do |content|
7
- if is_svg?(content)
8
- content.analyse(:svg_properties)[:height]
9
- elsif original
10
- original.call(content)
11
- end
12
- end
13
- end
14
- end
15
- end
16
- end
@@ -1,17 +0,0 @@
1
- module DragonflySvg
2
- module Analysers
3
- class LandscapeAnalyser < Base
4
- def initialize(app)
5
- original = app.analysers.items[:landscape]
6
- app.add_analyser(:landscape) do |content|
7
- if is_svg?(content)
8
- attrs = content.analyse(:svg_properties)
9
- attrs[:width] >= attrs[:height]
10
- elsif original
11
- original.call(content)
12
- end
13
- end
14
- end
15
- end
16
- end
17
- end
@@ -1,17 +0,0 @@
1
- module DragonflySvg
2
- module Analysers
3
- class PortraitAnalyser < Base
4
- def initialize(app)
5
- original = app.analysers.items[:portrait]
6
- app.add_analyser(:portrait) do |content|
7
- if is_svg?(content)
8
- attrs = content.analyse(:svg_properties)
9
- attrs[:width] <= attrs[:height]
10
- elsif original
11
- original.call(content)
12
- end
13
- end
14
- end
15
- end
16
- end
17
- end
@@ -1,16 +0,0 @@
1
- module DragonflySvg
2
- module Analysers
3
- class WidthAnalyser < Base
4
- def initialize(app)
5
- original = app.analysers.items[:width]
6
- app.add_analyser(:width) do |content|
7
- if is_svg?(content)
8
- content.analyse(:svg_properties)[:width]
9
- elsif original
10
- original.call(content)
11
- end
12
- end
13
- end
14
- end
15
- end
16
- end
Binary file