dragonfly_svg 0.0.4 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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