inline_svg 1.3.0 → 1.10.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.
@@ -4,7 +4,7 @@ module InlineSvg
4
4
  document = Nokogiri::XML::Document.parse(svg_file)
5
5
  Transformations.lookup(transform_params).reduce(document) do |doc, transformer|
6
6
  transformer.transform(doc)
7
- end.to_html
7
+ end.to_html.strip
8
8
  end
9
9
  end
10
10
  end
@@ -1,3 +1,3 @@
1
1
  module InlineSvg
2
- VERSION = "1.3.0"
2
+ VERSION = "1.10.0"
3
3
  end
@@ -0,0 +1,60 @@
1
+ module InlineSvg
2
+ class WebpackAssetFinder
3
+ def self.find_asset(filename)
4
+ new(filename)
5
+ end
6
+
7
+ def initialize(filename)
8
+ @filename = filename
9
+ manifest_lookup = asset_helper.manifest.lookup(@filename)
10
+ @asset_path = manifest_lookup.present? ? URI(manifest_lookup).path : ""
11
+ end
12
+
13
+ def pathname
14
+ return if @asset_path.blank?
15
+
16
+ if asset_helper.dev_server.running?
17
+ dev_server_asset(@asset_path)
18
+ elsif asset_helper.config.public_path.present?
19
+ File.join(asset_helper.config.public_path, @asset_path)
20
+ end
21
+ end
22
+
23
+ private
24
+
25
+ def asset_helper
26
+ @asset_helper ||=
27
+ if defined?(::Shakapacker)
28
+ ::Shakapacker
29
+ else
30
+ ::Webpacker
31
+ end
32
+ end
33
+
34
+ def dev_server_asset(file_path)
35
+ asset = fetch_from_dev_server(file_path)
36
+
37
+ begin
38
+ Tempfile.new(file_path).tap do |file|
39
+ file.binmode
40
+ file.write(asset)
41
+ file.rewind
42
+ end
43
+ rescue StandardError => e
44
+ Rails.logger.error "[inline_svg] Error creating tempfile for #{@filename}: #{e}"
45
+ raise
46
+ end
47
+ end
48
+
49
+ def fetch_from_dev_server(file_path)
50
+ http = Net::HTTP.new(asset_helper.dev_server.host, asset_helper.dev_server.port)
51
+ http.use_ssl = asset_helper.dev_server.protocol == "https"
52
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
53
+
54
+ http.request(Net::HTTP::Get.new(file_path)).body
55
+ rescue StandardError => e
56
+ Rails.logger.error "[inline_svg] Error fetching #{@filename} from webpack-dev-server: #{e}"
57
+ raise
58
+ end
59
+ end
60
+ end
data/lib/inline_svg.rb CHANGED
@@ -3,11 +3,15 @@ require "inline_svg/action_view/helpers"
3
3
  require "inline_svg/asset_file"
4
4
  require "inline_svg/cached_asset_file"
5
5
  require "inline_svg/finds_asset_paths"
6
+ require "inline_svg/propshaft_asset_finder"
6
7
  require "inline_svg/static_asset_finder"
8
+ require "inline_svg/webpack_asset_finder"
7
9
  require "inline_svg/transform_pipeline"
8
10
  require "inline_svg/io_resource"
9
11
 
10
12
  require "inline_svg/railtie" if defined?(Rails)
13
+ require 'active_support'
14
+ require 'active_support/core_ext/object/blank'
11
15
  require 'active_support/core_ext/string'
12
16
  require 'nokogiri'
13
17
 
@@ -21,6 +25,7 @@ module InlineSvg
21
25
  @custom_transformations = {}
22
26
  @asset_file = InlineSvg::AssetFile
23
27
  @svg_not_found_css_class = nil
28
+ @raise_on_file_not_found = false
24
29
  end
25
30
 
26
31
  def asset_file=(custom_asset_file)
@@ -39,6 +44,8 @@ module InlineSvg
39
44
  def asset_finder=(finder)
40
45
  @asset_finder = if finder.respond_to?(:find_asset)
41
46
  finder
47
+ elsif finder.class.name == "Propshaft::Assembly"
48
+ InlineSvg::PropshaftAssetFinder
42
49
  else
43
50
  # fallback to a naive static asset finder
44
51
  # (sprokects >= 3.0 && config.assets.precompile = false
@@ -61,6 +68,14 @@ module InlineSvg
61
68
  @custom_transformations.merge!(Hash[ *[options.fetch(:attribute, :no_attribute), options] ])
62
69
  end
63
70
 
71
+ def raise_on_file_not_found=(value)
72
+ @raise_on_file_not_found = value
73
+ end
74
+
75
+ def raise_on_file_not_found?
76
+ !!@raise_on_file_not_found
77
+ end
78
+
64
79
  private
65
80
 
66
81
  def incompatible_transformation?(klass)
@@ -45,4 +45,49 @@ describe InlineSvg::FindsAssetPaths do
45
45
  expect(InlineSvg::FindsAssetPaths.by_filename('some-file')).to be_nil
46
46
  end
47
47
  end
48
+
49
+ context "when propshaft finder returns an object which supports only the pathname method" do
50
+ it "returns fully qualified file paths from Propshaft" do
51
+ propshaft = double('PropshaftDouble')
52
+
53
+ expect(propshaft).to receive(:find_asset).with('some-file').
54
+ and_return(double(pathname: Pathname('/full/path/to/some-file')))
55
+
56
+ InlineSvg.configure do |config|
57
+ config.asset_finder = propshaft
58
+ end
59
+
60
+ expect(InlineSvg::FindsAssetPaths.by_filename('some-file')).to eq Pathname('/full/path/to/some-file')
61
+ end
62
+ end
63
+
64
+ context "when webpack finder returns an object with a relative asset path" do
65
+ it "returns the fully qualified file path" do
66
+ webpacker = double('WebpackerDouble')
67
+
68
+ expect(webpacker).to receive(:find_asset).with('some-file').
69
+ and_return(double(filename: Pathname('/full/path/to/some-file')))
70
+
71
+ InlineSvg.configure do |config|
72
+ config.asset_finder = webpacker
73
+ end
74
+
75
+ expect(InlineSvg::FindsAssetPaths.by_filename('some-file')).to eq Pathname('/full/path/to/some-file')
76
+ end
77
+ end
78
+
79
+ context "when webpack finder returns an object with an absolute http asset path" do
80
+ it "returns the fully qualified file path" do
81
+ webpacker = double('WebpackerDouble')
82
+
83
+ expect(webpacker).to receive(:find_asset).with('some-file').
84
+ and_return(double(filename: Pathname('https://my-fancy-domain.test/full/path/to/some-file')))
85
+
86
+ InlineSvg.configure do |config|
87
+ config.asset_finder = webpacker
88
+ end
89
+
90
+ expect(InlineSvg::FindsAssetPaths.by_filename('some-file')).to eq Pathname('https://my-fancy-domain.test/full/path/to/some-file')
91
+ end
92
+ end
48
93
  end
@@ -13,29 +13,56 @@ describe InlineSvg::ActionView::Helpers do
13
13
 
14
14
  let(:helper) { ( Class.new { include InlineSvg::ActionView::Helpers } ).new }
15
15
 
16
- describe "#inline_svg" do
16
+ shared_examples "inline_svg helper" do |helper_method:|
17
17
 
18
18
  context "when passed the name of an SVG that does not exist" do
19
19
  after(:each) do
20
20
  InlineSvg.reset_configuration!
21
21
  end
22
22
 
23
+ context "and configured to raise" do
24
+ it "raises an exception" do
25
+ InlineSvg.configure do |config|
26
+ config.raise_on_file_not_found = true
27
+ end
28
+
29
+ allow(InlineSvg::AssetFile).to receive(:named).
30
+ with('some-missing-file.svg').
31
+ and_raise(InlineSvg::AssetFile::FileNotFound.new)
32
+
33
+ expect {
34
+ helper.send(helper_method, 'some-missing-file.svg')
35
+ }.to raise_error(InlineSvg::AssetFile::FileNotFound)
36
+ end
37
+ end
38
+
23
39
  it "returns an empty, html safe, SVG document as a placeholder" do
24
40
  allow(InlineSvg::AssetFile).to receive(:named).
25
41
  with('some-missing-file.svg').
26
42
  and_raise(InlineSvg::AssetFile::FileNotFound.new)
27
43
 
28
- output = helper.inline_svg('some-missing-file.svg')
44
+ output = helper.send(helper_method, 'some-missing-file.svg')
29
45
  expect(output).to eq "<svg><!-- SVG file not found: 'some-missing-file.svg' --></svg>"
30
46
  expect(output).to be_html_safe
31
47
  end
32
48
 
49
+ it "escapes malicious input" do
50
+ malicious = "--></svg><script>alert(1)</script><svg>.svg"
51
+ allow(InlineSvg::AssetFile).to receive(:named).
52
+ with(malicious).
53
+ and_raise(InlineSvg::AssetFile::FileNotFound.new)
54
+
55
+ output = helper.send(helper_method, malicious)
56
+ expect(output).to eq "<svg><!-- SVG file not found: '--&gt;&lt;/svg&gt;&lt;script&gt;alert(1)&lt;/script&gt;&lt;svg&gt;.svg' --></svg>"
57
+ expect(output).to be_html_safe
58
+ end
59
+
33
60
  it "gives a helpful hint when no .svg extension is provided in the filename" do
34
61
  allow(InlineSvg::AssetFile).to receive(:named).
35
62
  with('missing-file-with-no-extension').
36
63
  and_raise(InlineSvg::AssetFile::FileNotFound.new)
37
64
 
38
- output = helper.inline_svg('missing-file-with-no-extension')
65
+ output = helper.send(helper_method, 'missing-file-with-no-extension')
39
66
  expect(output).to eq "<svg><!-- SVG file not found: 'missing-file-with-no-extension' (Try adding .svg to your filename) --></svg>"
40
67
  end
41
68
 
@@ -48,7 +75,7 @@ describe InlineSvg::ActionView::Helpers do
48
75
  with('some-other-missing-file.svg').
49
76
  and_raise(InlineSvg::AssetFile::FileNotFound.new)
50
77
 
51
- output = helper.inline_svg('some-other-missing-file.svg')
78
+ output = helper.send(helper_method, 'some-other-missing-file.svg')
52
79
  expect(output).to eq "<svg class='missing-svg'><!-- SVG file not found: 'some-other-missing-file.svg' --></svg>"
53
80
  expect(output).to be_html_safe
54
81
  end
@@ -59,11 +86,9 @@ describe InlineSvg::ActionView::Helpers do
59
86
  with('missing.svg').
60
87
  and_raise(InlineSvg::AssetFile::FileNotFound.new)
61
88
 
62
- fallback_file = <<-SVG
63
- <svg xmlns="http://www.w3.org/2000/svg" xml:lang="en"><!-- This is a comment --></svg>
64
- SVG
89
+ fallback_file = '<svg xmlns="http://www.w3.org/2000/svg" xml:lang="en"><!-- This is a comment --></svg>'
65
90
  allow(InlineSvg::AssetFile).to receive(:named).with('fallback.svg').and_return(fallback_file)
66
- expect(helper.inline_svg('missing.svg', fallback: 'fallback.svg')).to eq fallback_file
91
+ expect(helper.send(helper_method, 'missing.svg', fallback: 'fallback.svg')).to eq fallback_file
67
92
  end
68
93
  end
69
94
  end
@@ -72,76 +97,54 @@ SVG
72
97
 
73
98
  context "and no options" do
74
99
  it "returns a html safe version of the file's contents" do
75
- example_file = <<-SVG
76
- <svg xmlns="http://www.w3.org/2000/svg" xml:lang="en"><!-- This is a comment --></svg>
77
- SVG
100
+ example_file = '<svg xmlns="http://www.w3.org/2000/svg" xml:lang="en"><!-- This is a comment --></svg>'
78
101
  allow(InlineSvg::AssetFile).to receive(:named).with('some-file').and_return(example_file)
79
- expect(helper.inline_svg('some-file')).to eq example_file
102
+ expect(helper.send(helper_method, 'some-file')).to eq example_file
80
103
  end
81
104
  end
82
105
 
83
106
  context "and the 'title' option" do
84
107
  it "adds the title node to the SVG output" do
85
- input_svg = <<-SVG
86
- <svg xmlns="http://www.w3.org/2000/svg" role="presentation" xml:lang="en"></svg>
87
- SVG
88
- expected_output = <<-SVG
89
- <svg xmlns="http://www.w3.org/2000/svg" role="presentation" xml:lang="en"><title>A title</title></svg>
90
- SVG
108
+ input_svg = '<svg xmlns="http://www.w3.org/2000/svg" role="presentation" xml:lang="en"></svg>'
109
+ expected_output = '<svg xmlns="http://www.w3.org/2000/svg" role="presentation" xml:lang="en"><title>A title</title></svg>'
91
110
  allow(InlineSvg::AssetFile).to receive(:named).with('some-file').and_return(input_svg)
92
- expect(helper.inline_svg('some-file', title: 'A title')).to eq expected_output
111
+ expect(helper.send(helper_method, 'some-file', title: 'A title')).to eq expected_output
93
112
  end
94
113
  end
95
114
 
96
115
  context "and the 'desc' option" do
97
116
  it "adds the description node to the SVG output" do
98
- input_svg = <<-SVG
99
- <svg xmlns="http://www.w3.org/2000/svg" role="presentation" xml:lang="en"></svg>
100
- SVG
101
- expected_output = <<-SVG
102
- <svg xmlns="http://www.w3.org/2000/svg" role="presentation" xml:lang="en"><desc>A description</desc></svg>
103
- SVG
117
+ input_svg = '<svg xmlns="http://www.w3.org/2000/svg" role="presentation" xml:lang="en"></svg>'
118
+ expected_output = '<svg xmlns="http://www.w3.org/2000/svg" role="presentation" xml:lang="en"><desc>A description</desc></svg>'
104
119
  allow(InlineSvg::AssetFile).to receive(:named).with('some-file').and_return(input_svg)
105
- expect(helper.inline_svg('some-file', desc: 'A description')).to eq expected_output
120
+ expect(helper.send(helper_method, 'some-file', desc: 'A description')).to eq expected_output
106
121
  end
107
122
  end
108
123
 
109
124
  context "and the 'nocomment' option" do
110
125
  it "strips comments and other unknown/unsafe nodes from the output" do
111
- input_svg = <<-SVG
112
- <svg xmlns="http://www.w3.org/2000/svg" xml:lang="en"><!-- This is a comment --></svg>
113
- SVG
114
- expected_output = <<-SVG
115
- <svg xmlns="http://www.w3.org/2000/svg" xml:lang="en"></svg>
116
- SVG
126
+ input_svg = '<svg xmlns="http://www.w3.org/2000/svg" xml:lang="en"><!-- This is a comment --></svg>'
127
+ expected_output = '<svg xmlns="http://www.w3.org/2000/svg" xml:lang="en"></svg>'
117
128
  allow(InlineSvg::AssetFile).to receive(:named).with('some-file').and_return(input_svg)
118
- expect(helper.inline_svg('some-file', nocomment: true)).to eq expected_output
129
+ expect(helper.send(helper_method, 'some-file', nocomment: true)).to eq expected_output
119
130
  end
120
131
  end
121
132
 
122
133
  context "and the 'aria_hidden' option" do
123
134
  it "sets 'aria-hidden=true' in the output" do
124
- input_svg = <<-SVG
125
- <svg xmlns="http://www.w3.org/2000/svg" xml:lang="en"></svg>
126
- SVG
127
- expected_output = <<-SVG
128
- <svg xmlns="http://www.w3.org/2000/svg" xml:lang="en" aria-hidden="true"></svg>
129
- SVG
135
+ input_svg = '<svg xmlns="http://www.w3.org/2000/svg" xml:lang="en"></svg>'
136
+ expected_output = '<svg xmlns="http://www.w3.org/2000/svg" xml:lang="en" aria-hidden="true"></svg>'
130
137
  allow(InlineSvg::AssetFile).to receive(:named).with('some-file').and_return(input_svg)
131
- expect(helper.inline_svg('some-file', aria_hidden: true)).to eq expected_output
138
+ expect(helper.send(helper_method, 'some-file', aria_hidden: true)).to eq expected_output
132
139
  end
133
140
  end
134
141
 
135
142
  context "and all options" do
136
143
  it "applies all expected transformations to the output" do
137
- input_svg = <<-SVG
138
- <svg xmlns="http://www.w3.org/2000/svg" xml:lang="en"><!-- This is a comment --></svg>
139
- SVG
140
- expected_output = <<-SVG
141
- <svg xmlns="http://www.w3.org/2000/svg" xml:lang="en"><title>A title</title><desc>A description</desc></svg>
142
- SVG
144
+ input_svg = '<svg xmlns="http://www.w3.org/2000/svg" xml:lang="en"><!-- This is a comment --></svg>'
145
+ expected_output = '<svg xmlns="http://www.w3.org/2000/svg" xml:lang="en"><title>A title</title><desc>A description</desc></svg>'
143
146
  allow(InlineSvg::AssetFile).to receive(:named).with('some-file').and_return(input_svg)
144
- expect(helper.inline_svg('some-file', title: 'A title', desc: 'A description', nocomment: true)).to eq expected_output
147
+ expect(helper.send(helper_method, 'some-file', title: 'A title', desc: 'A description', nocomment: true)).to eq expected_output
145
148
  end
146
149
  end
147
150
 
@@ -157,14 +160,10 @@ SVG
157
160
  end
158
161
 
159
162
  it "applies custm transformations to the output" do
160
- input_svg = <<-SVG
161
- <svg></svg>
162
- SVG
163
- expected_output = <<-SVG
164
- <svg custom="some value"></svg>
165
- SVG
163
+ input_svg = '<svg></svg>'
164
+ expected_output = '<svg custom="some value"></svg>'
166
165
  allow(InlineSvg::AssetFile).to receive(:named).with('some-file').and_return(input_svg)
167
- expect(helper.inline_svg('some-file', custom: 'some value')).to eq expected_output
166
+ expect(helper.send(helper_method, 'some-file', custom: 'some value')).to eq expected_output
168
167
  end
169
168
  end
170
169
 
@@ -185,7 +184,7 @@ SVG
185
184
 
186
185
  allow(InlineSvg::AssetFile).to receive(:named).with('some-file').and_return(input_svg)
187
186
 
188
- expect(helper.inline_svg('some-file')).to eq "<svg custom=\"default value\"></svg>\n"
187
+ expect(helper.send(helper_method, 'some-file')).to eq "<svg custom=\"default value\"></svg>"
189
188
  end
190
189
  end
191
190
 
@@ -195,7 +194,7 @@ SVG
195
194
 
196
195
  allow(InlineSvg::AssetFile).to receive(:named).with('some-file').and_return(input_svg)
197
196
 
198
- expect(helper.inline_svg('some-file', custom: 'some value')).to eq "<svg custom=\"some value\"></svg>\n"
197
+ expect(helper.send(helper_method, 'some-file', custom: 'some value')).to eq "<svg custom=\"some value\"></svg>"
199
198
  end
200
199
  end
201
200
  end
@@ -207,13 +206,13 @@ SVG
207
206
  expect(InlineSvg::IOResource).to receive(:===).with(argument).and_return(true)
208
207
  expect(InlineSvg::IOResource).to receive(:read).with(argument)
209
208
  expect(InlineSvg::AssetFile).to_not receive(:named)
210
- helper.inline_svg(argument)
209
+ helper.send(helper_method, argument)
211
210
  end
212
211
  it 'accept filename' do
213
212
  expect(InlineSvg::IOResource).to receive(:===).with(argument).and_return(false)
214
213
  expect(InlineSvg::IOResource).to_not receive(:read)
215
214
  expect(InlineSvg::AssetFile).to receive(:named).with(argument)
216
- helper.inline_svg(argument)
215
+ helper.send(helper_method, argument)
217
216
  end
218
217
  end
219
218
  context 'when passed IO object argument' do
@@ -223,17 +222,39 @@ SVG
223
222
  it 'return valid svg' do
224
223
  expect(InlineSvg::IOResource).to receive(:===).with(io_object).and_return(true)
225
224
  expect(InlineSvg::IOResource).to receive(:read).with(io_object).and_return("<svg><!-- Test IO --></svg>")
226
- output = helper.inline_svg(io_object)
227
- expect(output).to eq "<svg><!-- Test IO --></svg>\n"
225
+ output = helper.send(helper_method, io_object)
226
+ expect(output).to eq "<svg><!-- Test IO --></svg>"
228
227
  expect(output).to be_html_safe
229
228
  end
230
229
 
231
230
  it 'return valid svg for file' do
232
- output = helper.inline_svg(File.new(file_path))
233
- expect(output).to eq "<svg xmlns=\"http://www.w3.org/2000/svg\" xml:lang=\"en\" role=\"presentation\"><!-- This is a test comment --></svg>\n"
231
+ output = helper.send(helper_method, File.new(file_path))
232
+ expect(output).to eq "<svg xmlns=\"http://www.w3.org/2000/svg\" xml:lang=\"en\" role=\"presentation\"><!-- This is a test comment --></svg>"
234
233
  expect(output).to be_html_safe
235
234
  end
236
235
 
237
236
  end
237
+
238
+ context 'default output' do
239
+ it "returns an SVG tag without any pre or post whitespace characters" do
240
+ input_svg = '<svg></svg>'
241
+
242
+ allow(InlineSvg::AssetFile).to receive(:named).with('some-file').and_return(input_svg)
243
+
244
+ expect(helper.send(helper_method, 'some-file')).to eq "<svg></svg>"
245
+ end
246
+ end
247
+ end
248
+
249
+ describe '#inline_svg' do
250
+ it_behaves_like "inline_svg helper", helper_method: :inline_svg
251
+ end
252
+
253
+ describe '#inline_svg_tag' do
254
+ it_behaves_like "inline_svg helper", helper_method: :inline_svg_tag
255
+ end
256
+
257
+ describe '#inline_svg_tag' do
258
+ it_behaves_like "inline_svg helper", helper_method: :inline_svg_pack_tag
238
259
  end
239
260
  end
@@ -5,6 +5,6 @@ describe InlineSvg::IdGenerator do
5
5
  randomizer = -> { "some-random-value" }
6
6
 
7
7
  expect(InlineSvg::IdGenerator.generate("some-base", "some-salt", randomness: randomizer)).
8
- to eq("t2c17mkqnvopy36iccxspura7wnreqf")
8
+ to eq("at2c17mkqnvopy36iccxspura7wnreqf")
9
9
  end
10
10
  end
@@ -47,7 +47,7 @@ describe InlineSvg do
47
47
  end
48
48
 
49
49
  context "configuring a custom asset file" do
50
- it "falls back to the built-in asset file implementation by deafult" do
50
+ it "falls back to the built-in asset file implementation by default" do
51
51
  expect(InlineSvg.configuration.asset_file).to eq(InlineSvg::AssetFile)
52
52
  end
53
53
 
@@ -0,0 +1,23 @@
1
+ require_relative '../lib/inline_svg'
2
+
3
+ describe InlineSvg::PropshaftAssetFinder do
4
+ context "when the file is not found" do
5
+ it "returns nil" do
6
+ stub_const('Rails', double('Rails').as_null_object)
7
+ expect(::Rails.application.assets.load_path).to receive(:find).with('some-file').and_return(nil)
8
+
9
+ expect(InlineSvg::PropshaftAssetFinder.find_asset('some-file').pathname).to be_nil
10
+ end
11
+ end
12
+
13
+ context "when the file is found" do
14
+ it "returns fully qualified file paths from Propshaft" do
15
+ stub_const('Rails', double('Rails').as_null_object)
16
+ asset = double('Asset')
17
+ expect(asset).to receive(:path).and_return(Pathname.new('/full/path/to/some-file'))
18
+ expect(::Rails.application.assets.load_path).to receive(:find).with('some-file').and_return(asset)
19
+
20
+ expect(InlineSvg::PropshaftAssetFinder.find_asset('some-file').pathname).to eq Pathname('/full/path/to/some-file')
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,25 @@
1
+ require_relative '../lib/inline_svg'
2
+
3
+ describe InlineSvg::StaticAssetFinder do
4
+ context "when the file is not found" do
5
+ it "returns nil" do
6
+ stub_const('Rails', double('Rails').as_null_object)
7
+ expect(::Rails.application.config.assets).to receive(:compile).and_return(true)
8
+
9
+ expect(described_class.find_asset('some-file').pathname).to be_nil
10
+ end
11
+ end
12
+
13
+ context "when the file is found" do
14
+ it "returns fully qualified file path from Sprockets" do
15
+ stub_const('Rails', double('Rails').as_null_object)
16
+ expect(::Rails.application.config.assets).to receive(:compile).and_return(true)
17
+ pathname = Pathname.new('/full/path/to/some-file')
18
+ asset = double('Asset')
19
+ expect(asset).to receive(:filename).and_return(pathname)
20
+ expect(::Rails.application.assets).to receive(:[]).with('some-file').and_return(asset)
21
+
22
+ expect(described_class.find_asset('some-file').pathname).to eq(pathname)
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,13 @@
1
+ require 'inline_svg/transform_pipeline'
2
+
3
+ describe InlineSvg::TransformPipeline::Transformations::ViewBox do
4
+ it "adds viewBox attribute to a SVG document" do
5
+ document = Nokogiri::XML::Document.parse('<svg>Some document</svg>')
6
+ transformation =
7
+ InlineSvg::TransformPipeline::Transformations::ViewBox
8
+ .create_with_value("0 0 100 100")
9
+ expect(transformation.transform(document).to_html).to eq(
10
+ "<svg viewBox=\"0 0 100 100\">Some document</svg>\n"
11
+ )
12
+ end
13
+ end
@@ -21,6 +21,7 @@ describe InlineSvg::TransformPipeline::Transformations do
21
21
  size: 'irrelevant',
22
22
  height: 'irrelevant',
23
23
  width: 'irrelevant',
24
+ view_box: 'irrelevant',
24
25
  id: 'irrelevant',
25
26
  data: 'irrelevant',
26
27
  preserve_aspect_ratio: 'irrelevant',
@@ -37,6 +38,7 @@ describe InlineSvg::TransformPipeline::Transformations do
37
38
  InlineSvg::TransformPipeline::Transformations::Size,
38
39
  InlineSvg::TransformPipeline::Transformations::Height,
39
40
  InlineSvg::TransformPipeline::Transformations::Width,
41
+ InlineSvg::TransformPipeline::Transformations::ViewBox,
40
42
  InlineSvg::TransformPipeline::Transformations::IdAttribute,
41
43
  InlineSvg::TransformPipeline::Transformations::DataAttributes,
42
44
  InlineSvg::TransformPipeline::Transformations::PreserveAspectRatio,
@@ -0,0 +1,23 @@
1
+ require_relative '../lib/inline_svg'
2
+
3
+ describe InlineSvg::WebpackAssetFinder do
4
+ context "when the file is not found" do
5
+ it "returns nil" do
6
+ stub_const('Rails', double('Rails').as_null_object)
7
+ stub_const('Webpacker', double('Webpacker').as_null_object)
8
+ expect(::Webpacker.manifest).to receive(:lookup).with('some-file').and_return(nil)
9
+
10
+ expect(described_class.find_asset('some-file').pathname).to be_nil
11
+ end
12
+ end
13
+
14
+ context "when Shakapacker is defined" do
15
+ it "uses the new spelling" do
16
+ stub_const('Rails', double('Rails').as_null_object)
17
+ stub_const('Shakapacker', double('Shakapacker').as_null_object)
18
+ expect(::Shakapacker.manifest).to receive(:lookup).with('some-file').and_return(nil)
19
+
20
+ expect(described_class.find_asset('some-file').pathname).to be_nil
21
+ end
22
+ end
23
+ end