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.
- checksums.yaml +5 -5
- data/.github/workflows/integration_test.yml +47 -0
- data/.github/workflows/rails_6_webpacker_integration_tests.yaml +62 -0
- data/.github/workflows/ruby.yml +20 -0
- data/CHANGELOG.md +94 -5
- data/README.md +42 -16
- data/inline_svg.gemspec +1 -1
- data/lib/inline_svg/action_view/helpers.rb +38 -4
- data/lib/inline_svg/cached_asset_file.rb +3 -12
- data/lib/inline_svg/finds_asset_paths.rb +1 -1
- data/lib/inline_svg/id_generator.rb +3 -1
- data/lib/inline_svg/propshaft_asset_finder.rb +16 -0
- data/lib/inline_svg/railtie.rb +3 -2
- data/lib/inline_svg/static_asset_finder.rb +5 -2
- data/lib/inline_svg/transform_pipeline/transformations/view_box.rb +9 -0
- data/lib/inline_svg/transform_pipeline/transformations.rb +8 -3
- data/lib/inline_svg/transform_pipeline.rb +1 -1
- data/lib/inline_svg/version.rb +1 -1
- data/lib/inline_svg/webpack_asset_finder.rb +60 -0
- data/lib/inline_svg.rb +15 -0
- data/spec/finds_asset_paths_spec.rb +45 -0
- data/spec/helpers/inline_svg_spec.rb +83 -62
- data/spec/id_generator_spec.rb +1 -1
- data/spec/inline_svg_spec.rb +1 -1
- data/spec/propshaft_asset_finder_spec.rb +23 -0
- data/spec/static_asset_finder_spec.rb +25 -0
- data/spec/transformation_pipeline/transformations/view_box_spec.rb +13 -0
- data/spec/transformation_pipeline/transformations_spec.rb +2 -0
- data/spec/webpack_asset_finder_spec.rb +23 -0
- metadata +22 -10
- data/circle.yml +0 -3
data/lib/inline_svg/version.rb
CHANGED
@@ -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
|
-
|
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.
|
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: '--></svg><script>alert(1)</script><svg>.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.
|
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.
|
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 =
|
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.
|
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 =
|
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.
|
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 =
|
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.
|
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 =
|
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.
|
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 =
|
112
|
-
<svg xmlns="http://www.w3.org/2000/svg" xml:lang="en"
|
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.
|
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 =
|
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.
|
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 =
|
138
|
-
<svg xmlns="http://www.w3.org/2000/svg" xml:lang="en"
|
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.
|
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 =
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
227
|
-
expect(output).to eq "<svg><!-- Test IO --></svg
|
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.
|
233
|
-
expect(output).to eq "<svg xmlns=\"http://www.w3.org/2000/svg\" xml:lang=\"en\" role=\"presentation\"><!-- This is a test comment --></svg
|
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
|
data/spec/id_generator_spec.rb
CHANGED
@@ -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("
|
8
|
+
to eq("at2c17mkqnvopy36iccxspura7wnreqf")
|
9
9
|
end
|
10
10
|
end
|
data/spec/inline_svg_spec.rb
CHANGED
@@ -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
|
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
|