svg_hearts_you 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (98) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +22 -0
  3. data/.rspec +1 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +265 -0
  7. data/Rakefile +46 -0
  8. data/features/middleman.feature +19 -0
  9. data/features/step_definitions/steps.rb +3 -0
  10. data/features/support/env.rb +8 -0
  11. data/fixtures/middleman-extension-config-style/config.rb +1 -0
  12. data/fixtures/middleman-extension-config-style/source/circle.svg +7 -0
  13. data/fixtures/middleman-extension-config-style/source/index.html.erb +2 -0
  14. data/fixtures/middleman-extension-default-config/config.rb +1 -0
  15. data/fixtures/middleman-extension-default-config/source/images/circle.svg +7 -0
  16. data/fixtures/middleman-extension-default-config/source/index.html.erb +2 -0
  17. data/fixtures/middleman-svg_hearts_you-config-style/config.rb +6 -0
  18. data/fixtures/middleman-svg_hearts_you-config-style/source/circle.svg +7 -0
  19. data/fixtures/middleman-svg_hearts_you-config-style/source/index.html.erb +2 -0
  20. data/lib/svg_hearts_you.rb +11 -0
  21. data/lib/svg_hearts_you/configuration.rb +23 -0
  22. data/lib/svg_hearts_you/helpers.rb +165 -0
  23. data/lib/svg_hearts_you/middleman_extension.rb +31 -0
  24. data/lib/svg_hearts_you/module.rb +19 -0
  25. data/lib/svg_hearts_you/railtie.rb +9 -0
  26. data/lib/svg_hearts_you/version.rb +3 -0
  27. data/spec/module/configuration_spec.rb +18 -0
  28. data/spec/module/svg_hearts_you_spec.rb +192 -0
  29. data/spec/module/svgs/circle.svg +7 -0
  30. data/spec/module/svgs/logos/back-icon.svg +12 -0
  31. data/spec/module/svgs/logos/logout-icon.svg +15 -0
  32. data/spec/module/svgs/logos/plus-icon.svg +12 -0
  33. data/spec/module/svgs/logos/search-icon.svg +12 -0
  34. data/spec/module/svgs/logos/x-icon.svg +12 -0
  35. data/spec/module/svgs/sapphire.svg +15 -0
  36. data/spec/module/svgs/shapes/polygon.svg +10 -0
  37. data/spec/module/svgs/shapes/star.svg +10 -0
  38. data/spec/module/svgs/shapes/triangle.svg +10 -0
  39. data/spec/rails/dummy/README.rdoc +28 -0
  40. data/spec/rails/dummy/Rakefile +6 -0
  41. data/spec/rails/dummy/app/assets/images/.keep +0 -0
  42. data/spec/rails/dummy/app/assets/images/circle.svg +7 -0
  43. data/spec/rails/dummy/app/assets/images/circle_and_gems.svg +34 -0
  44. data/spec/rails/dummy/app/assets/images/logos/back-icon.svg +12 -0
  45. data/spec/rails/dummy/app/assets/images/logos/logout-icon.svg +15 -0
  46. data/spec/rails/dummy/app/assets/images/logos/plus-icon.svg +12 -0
  47. data/spec/rails/dummy/app/assets/images/logos/search-icon.svg +12 -0
  48. data/spec/rails/dummy/app/assets/images/logos/x-icon.svg +12 -0
  49. data/spec/rails/dummy/app/assets/images/shapes/polygon.svg +10 -0
  50. data/spec/rails/dummy/app/assets/images/shapes/star.svg +10 -0
  51. data/spec/rails/dummy/app/assets/images/shapes/triangle.svg +10 -0
  52. data/spec/rails/dummy/app/assets/javascripts/application.js +13 -0
  53. data/spec/rails/dummy/app/assets/stylesheets/application.css +15 -0
  54. data/spec/rails/dummy/app/controllers/application_controller.rb +5 -0
  55. data/spec/rails/dummy/app/controllers/concerns/.keep +0 -0
  56. data/spec/rails/dummy/app/controllers/pages_controller.rb +7 -0
  57. data/spec/rails/dummy/app/helpers/application_helper.rb +2 -0
  58. data/spec/rails/dummy/app/mailers/.keep +0 -0
  59. data/spec/rails/dummy/app/models/.keep +0 -0
  60. data/spec/rails/dummy/app/models/concerns/.keep +0 -0
  61. data/spec/rails/dummy/app/views/layouts/application.html.erb +13 -0
  62. data/spec/rails/dummy/app/views/pages/basic.html.erb +13 -0
  63. data/spec/rails/dummy/app/views/pages/folder.html.erb +8 -0
  64. data/spec/rails/dummy/bin/bundle +3 -0
  65. data/spec/rails/dummy/bin/rails +4 -0
  66. data/spec/rails/dummy/bin/rake +4 -0
  67. data/spec/rails/dummy/config.ru +4 -0
  68. data/spec/rails/dummy/config/application.rb +27 -0
  69. data/spec/rails/dummy/config/boot.rb +5 -0
  70. data/spec/rails/dummy/config/database.yml +25 -0
  71. data/spec/rails/dummy/config/environment.rb +5 -0
  72. data/spec/rails/dummy/config/environments/development.rb +37 -0
  73. data/spec/rails/dummy/config/environments/production.rb +82 -0
  74. data/spec/rails/dummy/config/environments/test.rb +39 -0
  75. data/spec/rails/dummy/config/initializers/assets.rb +8 -0
  76. data/spec/rails/dummy/config/initializers/backtrace_silencers.rb +7 -0
  77. data/spec/rails/dummy/config/initializers/cookies_serializer.rb +3 -0
  78. data/spec/rails/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  79. data/spec/rails/dummy/config/initializers/inflections.rb +16 -0
  80. data/spec/rails/dummy/config/initializers/mime_types.rb +4 -0
  81. data/spec/rails/dummy/config/initializers/session_store.rb +3 -0
  82. data/spec/rails/dummy/config/initializers/wrap_parameters.rb +14 -0
  83. data/spec/rails/dummy/config/locales/en.yml +23 -0
  84. data/spec/rails/dummy/config/routes.rb +60 -0
  85. data/spec/rails/dummy/config/secrets.yml +22 -0
  86. data/spec/rails/dummy/db/development.sqlite3 +0 -0
  87. data/spec/rails/dummy/db/schema.rb +16 -0
  88. data/spec/rails/dummy/db/test.sqlite3 +0 -0
  89. data/spec/rails/dummy/lib/assets/.keep +0 -0
  90. data/spec/rails/dummy/log/.keep +0 -0
  91. data/spec/rails/dummy/public/404.html +67 -0
  92. data/spec/rails/dummy/public/422.html +67 -0
  93. data/spec/rails/dummy/public/500.html +66 -0
  94. data/spec/rails/dummy/public/favicon.ico +0 -0
  95. data/spec/rails/features/rails_svg_spec.rb +56 -0
  96. data/spec/spec_helper.rb +23 -0
  97. data/svg_hearts_you.gemspec +46 -0
  98. metadata +463 -0
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
3
+ <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" width="100" height="100" viewBox="0, 0, 100, 100">
4
+ <g id="Layer_1">
5
+ <path d="M50,100 C22.386,100 0,77.614 0,50 C0,22.386 22.386,0 50,-0 C77.614,-0 100,22.386 100,50 C100,77.614 77.614,100 50,100 z" fill="#4B5A65"/>
6
+ </g>
7
+ </svg>
@@ -0,0 +1,2 @@
1
+ <h1>Test</h1>
2
+ <%= svg_inline 'circle.svg' %>
@@ -0,0 +1,11 @@
1
+ begin
2
+ require "pry"
3
+ rescue LoadError
4
+ end
5
+
6
+ require 'svg_hearts_you/configuration'
7
+ require 'svg_hearts_you/module'
8
+ require 'svg_hearts_you/helpers'
9
+
10
+ require 'svg_hearts_you/railtie' if defined?(Rails)
11
+ require 'svg_hearts_you/middleman_extension' if defined?(Middleman)
@@ -0,0 +1,23 @@
1
+ module SvgHeartsYou
2
+ class Configuration
3
+ attr_accessor :svg_paths
4
+
5
+ def initialize
6
+ @svg_paths = []
7
+ end
8
+
9
+ # Include asset paths / image_paths with rails / middleman
10
+ def all_svg_paths
11
+ if defined?(Rails)
12
+ @svg_paths + rails_paths
13
+ else
14
+ @svg_paths
15
+ end
16
+ end
17
+
18
+ private
19
+ def rails_paths
20
+ Rails.application.config.assets.paths
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,165 @@
1
+ require 'nokogiri'
2
+
3
+ module SvgHeartsYou
4
+
5
+ def self.find_svg_file(filename)
6
+ configuration.all_svg_paths.each do |path|
7
+ file_path = File.join path, filename
8
+ if File.exists?(file_path)
9
+ return File.read file_path
10
+ end
11
+ end
12
+
13
+ # if not found, raise error
14
+ raise "File #{filename} not found"
15
+ end
16
+
17
+ def self.svgs_for_folder(folder_name)
18
+ configuration.all_svg_paths.each do |path|
19
+ folder_path = File.join path, folder_name
20
+ if File.exists?(folder_path) && File.directory?(folder_path)
21
+ Dir.chdir(folder_path)
22
+ return Dir.glob("*.svg*").map do |filename|
23
+ file_path = File.join folder_path, filename
24
+ { file: File.read(file_path), filename: filename }
25
+ # File.join(folder_name, filename)
26
+ end
27
+ end
28
+ end
29
+
30
+ # if not found, raise error
31
+ raise "Folder #{folder_name} not found"
32
+ end
33
+
34
+
35
+ module Helpers
36
+
37
+ def svg_inline(filename, options={})
38
+ svg_file = SvgHeartsYou::find_svg_file(filename)
39
+
40
+ doc = Nokogiri::HTML::DocumentFragment.parse(svg_file)
41
+ svg = doc.at_css 'svg'
42
+
43
+ # Attributes are added after
44
+ options.each do |key, value|
45
+ svg[key.to_s] = value
46
+ end
47
+
48
+ stringify(svg)
49
+ end
50
+
51
+ def svg_symbol(filename, options={})
52
+ folder_mode = options.delete(:folder)
53
+
54
+ if folder_mode
55
+ folders = [*filename]
56
+ read_files = []
57
+
58
+ folders.each do |folder_name|
59
+ read_files += SvgHeartsYou::svgs_for_folder(folder_name)
60
+ end
61
+
62
+ symbols = read_files.map do |file|
63
+ doc = Nokogiri::HTML::DocumentFragment.parse(file[:file])
64
+ { node: doc.at_css('svg'), filename: file[:filename] }
65
+ end
66
+ else
67
+ files = [*filename]
68
+ symbols = files.map do |file|
69
+ svg_file = SvgHeartsYou::find_svg_file(file)
70
+ doc = Nokogiri::HTML::DocumentFragment.parse(svg_file)
71
+ { node: doc.at_css('svg'), filename: file }
72
+ end
73
+ end
74
+
75
+ doc = Nokogiri::HTML::DocumentFragment.parse('')
76
+ wrapper_svg = Nokogiri::XML::Node.new 'svg', doc
77
+
78
+ wrapper_svg['version'] = '1.1'
79
+ wrapper_svg['xmlns'] = 'http://www.w3.org/2000/svg'
80
+ wrapper_svg['style'] = 'display: none;'
81
+
82
+ symbols.each do |symbol|
83
+ node = symbol[:node]
84
+
85
+ # Convert
86
+ node.name = 'symbol'
87
+ node['id'] = symbol[:filename].chomp('.svg')
88
+
89
+ # add `each` items here
90
+ if options[:each]
91
+ options[:each].each do |key, value|
92
+ node[key.to_s] = value
93
+ end
94
+ end
95
+
96
+ %w(version xmlns xmlns:xlink).each do |attr|
97
+ node.delete attr
98
+ end
99
+
100
+ if block_given?
101
+ attributes = {}
102
+ node.entries.each do |item|
103
+ attributes[item[0].to_sym] = item[1]
104
+ end
105
+
106
+ # Allow each symbol to be configured if block given
107
+ yield(attributes)
108
+
109
+ attributes.each do |key, value|
110
+ node[key.to_s] = value
111
+ end
112
+ end
113
+
114
+ wrapper_svg.add_child(node)
115
+ end
116
+
117
+ options.delete(:each)
118
+
119
+ # Put remaining options on parent svg tag
120
+ options.each do |key, value|
121
+ wrapper_svg[key.to_s] = value
122
+ end
123
+
124
+ stringify(wrapper_svg)
125
+ end
126
+
127
+ def svg_use(id, options={})
128
+ # Strip .svg extension if necessary
129
+ id.gsub!(/\.svg\z/, '')
130
+
131
+ # Add hash symbol to beginning if necessary
132
+ id = '#' + id unless id.include?('#')
133
+
134
+ doc = Nokogiri::HTML::DocumentFragment.parse <<-YAYUSE
135
+ <svg version="1.1" xmlns="http://www.w3.org/2000/svg">
136
+ <use xlink:href="#{id}">
137
+ </svg>
138
+ YAYUSE
139
+
140
+ svg = doc.at_css 'svg'
141
+
142
+ # TODO allow for the title and desc stuff
143
+ options.delete :title
144
+ options.delete :desc
145
+
146
+ options.each do |key, value|
147
+ svg[key.to_s] = value
148
+ end
149
+
150
+ stringify(svg)
151
+ end
152
+
153
+ private
154
+ def stringify(node)
155
+ str = node.to_html
156
+ str = str.html_safe if str.respond_to? :html_safe
157
+ str
158
+ end
159
+ end
160
+
161
+ # Add helpers as class methods on the SvgHeartsYou module
162
+ class << self
163
+ include Helpers
164
+ end
165
+ end
@@ -0,0 +1,31 @@
1
+ module SvgHeartsYou
2
+ module Extensions
3
+ class MiddlemanExtension < Middleman::Extension
4
+ option :svg_paths, [], 'Used to set custom search path for SvgHeartsYou gem'
5
+
6
+ def initialize(app, options_hash={}, &block)
7
+ super
8
+
9
+ # Configure gem if svg_paths option is set via middleman
10
+ if options_hash.key?(:svg_paths)
11
+ SvgHeartsYou.configure do |config|
12
+ config.svg_paths << options_hash[:svg_paths]
13
+ end
14
+ end
15
+ end
16
+
17
+ helpers do
18
+ include SvgHeartsYou::Helpers
19
+ end
20
+
21
+ def after_configuration
22
+ # Add middleman app's images_dir by default
23
+ SvgHeartsYou.configure do |config|
24
+ config.svg_paths << File.join(Dir.pwd, app.settings.source, app.settings.images_dir)
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+
31
+ ::Middleman::Extensions.register(:svg_hearts_you, SvgHeartsYou::Extensions::MiddlemanExtension)
@@ -0,0 +1,19 @@
1
+ module SvgHeartsYou
2
+ class << self
3
+ attr_accessor :configuration
4
+ end
5
+
6
+ # Allow a persistent configuration object to be set on the module
7
+ def self.configure
8
+ yield(configuration)
9
+ end
10
+
11
+ private
12
+ def self.configuration
13
+ @configuration ||= Configuration.new
14
+ end
15
+
16
+ def self.reset
17
+ @configuration = Configuration.new
18
+ end
19
+ end
@@ -0,0 +1,9 @@
1
+ module SvgHeartsYou
2
+ module Extensions
3
+ class Railtie < ::Rails::Railtie
4
+ initializer 'SvgHeartsYou.add_helpers' do
5
+ ActionView::Base.send :include, SvgHeartsYou::Helpers
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,3 @@
1
+ module SvgHeartsYou
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ module SvgHeartsYou
4
+ describe Configuration do
5
+ describe '#svg_path' do
6
+
7
+ it 'has a default value of nil' do
8
+ expect(Configuration.new.svg_paths).to eq([])
9
+ end
10
+
11
+ it 'can set the svg_path' do
12
+ config = Configuration.new
13
+ config.svg_paths << '/some/path';
14
+ expect(config.svg_paths).to eq(['/some/path'])
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,192 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe SvgHeartsYou do
4
+
5
+ let(:test_svg_path) { File.join File.dirname(__FILE__), 'svgs' }
6
+ let!(:svg_file) { 'sapphire.svg' }
7
+ let!(:svg_file2) { 'circle.svg' }
8
+ let!(:svg_folder) { 'shapes' }
9
+ let!(:svg_folder2) { 'logos' }
10
+ let!(:nonexistent_svg_file) { 'nope-nope.svg' }
11
+
12
+ let!(:unconfigured_message) { "File #{svg_file} not found" }
13
+ let!(:missing_file_message) { "File #{nonexistent_svg_file} not found" }
14
+
15
+
16
+ # Singleton module is messy for random order tests, so wipe state after each
17
+ after(:each) do
18
+ SvgHeartsYou.reset
19
+ end
20
+
21
+ # Generically tests methods (passed as symbol) that are
22
+ # expected to throw runtime errors
23
+ shared_examples 'methods that throw error on file not found' do |method|
24
+ it 'throws a RuntimeError when not file not found' do
25
+ expect{subject.send(method, svg_file)}.to raise_error(RuntimeError, unconfigured_message)
26
+ end
27
+ end
28
+
29
+ # Examples for methods that may throw error when files are missing
30
+ shared_examples 'method using file' do |method|
31
+ it 'throws a RuntimeError when file is not found' do
32
+ expect{subject.send(method, nonexistent_svg_file)}.to raise_error(RuntimeError, missing_file_message)
33
+ end
34
+ end
35
+
36
+ # Tests that are used in both unconfigured and configured contexts
37
+ shared_examples 'svg use' do
38
+ it 'returns SVG use statement' do
39
+ svg_content = subject.svg_use '#id'
40
+ expect(svg_content).to include '<use xlink:href="#id">'
41
+ end
42
+
43
+ it 'adds hash at beginning if not given or external link' do
44
+ svg_content = subject.svg_use 'id'
45
+ expect(svg_content).to include '<use xlink:href="#id">'
46
+ end
47
+
48
+ it 'adds classes and ids to svg tag' do
49
+ svg_content = subject.svg_use '#id', id: 'hearts', class: 'love'
50
+ expect(svg_content).to have_tag('svg', with: { id: 'hearts', class: 'love' })
51
+ end
52
+
53
+ it 'adds any attribute to svg tag' do
54
+ attributes = { width: '64px', height: '48px', viewport: '0, 0, 12, 24' }
55
+ svg_content = subject.svg_use '#id', attributes
56
+ expect(svg_content).to have_tag('svg', with: attributes)
57
+ end
58
+
59
+ it 'strips .svg extension if necessary' do
60
+ svg_content = subject.svg_use '#circle.svg'
61
+ expect(svg_content).to include '<use xlink:href="#circle">'
62
+ expect(svg_content).to_not include '<use xlink:href="#circle.svg">'
63
+ end
64
+ end
65
+
66
+
67
+ describe 'without configuration' do
68
+ describe 'self.configuration' do
69
+ it 'defaults attributes to nil' do
70
+ expect(SvgHeartsYou.configuration.svg_paths).to eq([])
71
+ end
72
+ end
73
+
74
+ describe '#svg_inline' do
75
+ it_behaves_like 'methods that throw error on file not found', :svg_inline
76
+ end
77
+
78
+ describe '#svg_use' do
79
+ include_examples 'svg use'
80
+ end
81
+
82
+ describe '#svg_symbol' do
83
+ it_behaves_like 'methods that throw error on file not found', :svg_symbol
84
+ end
85
+ end
86
+
87
+ describe 'with configuration' do
88
+ before do
89
+ SvgHeartsYou.configure do |config|
90
+ config.svg_paths << test_svg_path
91
+ end
92
+ end
93
+
94
+ describe 'self.configuration' do
95
+ it 'is configured to the the current directory' do
96
+ expect(SvgHeartsYou.configuration.svg_paths).to eq([test_svg_path])
97
+ end
98
+ end
99
+
100
+ describe '#svg_inline' do
101
+ it_behaves_like 'method using file', :svg_inline
102
+
103
+ it 'returns contents of SVG file without XML headers' do
104
+ svg_content = subject.svg_inline 'sapphire.svg'
105
+
106
+ expect(svg_content).to have_tag('svg')
107
+ expect(svg_content).not_to include('<xml')
108
+ expect(svg_content).not_to include('DOCTYPE')
109
+ end
110
+ end
111
+
112
+ describe '#svg_use' do
113
+ include_examples 'svg use'
114
+ end
115
+
116
+ describe '#svg_symbol' do
117
+ let(:sapphire_svg_attributes) {{
118
+ x: '0',
119
+ y: '0',
120
+ width: '64',
121
+ height: '52',
122
+ viewbox: '0, 0, 64, 52'
123
+ }}
124
+
125
+ it_behaves_like 'method using file', :svg_symbol
126
+
127
+ it 'returns the SVG contents in a symbol' do
128
+ svg_content = subject.svg_symbol svg_file
129
+
130
+ expect(svg_content).not_to have_tag('svg', with: sapphire_svg_attributes)
131
+ expect(svg_content).to have_tag('svg>symbol', with: sapphire_svg_attributes)
132
+ expect(svg_content).to have_tag('svg>symbol', with: { id: 'sapphire' })
133
+ expect(svg_content).not_to have_tag('svg>*:not(symbol)')
134
+ expect(svg_content).to have_tag('svg>symbol>*')
135
+ end
136
+
137
+ it 'applies extra attributes to top level svg' do
138
+ new_id = 'hey-there'
139
+
140
+ svg_content = subject.svg_symbol svg_file, id: new_id
141
+ expect(svg_content).to have_tag('svg', with: {id: new_id})
142
+ end
143
+
144
+ it 'applies or replaces attributes on each symbol with the `each` parameter' do
145
+ new_viewbox = '0, 0, 100, 100'
146
+ new_class = 'shape'
147
+
148
+ updated_attributes = sapphire_svg_attributes.clone
149
+ updated_attributes[:viewbox] = new_viewbox
150
+ updated_attributes[:class] = new_class
151
+
152
+ svg_content = subject.svg_symbol svg_file, each: { viewbox: new_viewbox, class: new_class }
153
+ expect(svg_content).to have_tag('svg>symbol', with: updated_attributes)
154
+ end
155
+
156
+ it 'pulls in multiple files' do
157
+ svg_content = subject.svg_symbol [svg_file, svg_file2]
158
+ expect(svg_content).to have_tag('svg>symbol', count: 2)
159
+ end
160
+
161
+ it 'pulls in a given folder with `folder` parameter' do
162
+ svg_content = subject.svg_symbol svg_folder, folder: true
163
+ expect(svg_content).to have_tag('svg>symbol', with: { id: 'polygon' })
164
+ expect(svg_content).to have_tag('svg>symbol', with: { id: 'star' })
165
+ expect(svg_content).to have_tag('svg>symbol', with: { id: 'triangle' })
166
+ end
167
+
168
+ it 'pulls in multiple folders with `folder` parameter' do
169
+ svg_content = subject.svg_symbol [svg_folder, svg_folder2], folder: true
170
+ expect(svg_content).to have_tag('svg>symbol', count: 8)
171
+ end
172
+
173
+ it 'takes a block that can modify each symbol' do
174
+ new_class = 'shape'
175
+
176
+ svg_content = subject.svg_symbol svg_folder, folder: true do |attributes|
177
+ attributes[:id] = attributes[:id] + '-extra'
178
+ attributes[:class] = 'shape'
179
+ end
180
+
181
+ expect(svg_content).to have_tag('svg>symbol', with: { id: 'polygon-extra', class: new_class })
182
+ expect(svg_content).to have_tag('svg>symbol', with: { id: 'star-extra', class: new_class })
183
+ expect(svg_content).to have_tag('svg>symbol', with: { id: 'triangle-extra', class: new_class })
184
+ end
185
+ end
186
+ end
187
+
188
+ # Meta test to make sure state is wiped
189
+ it 'correctly resets configuration at end of tests' do
190
+ expect(SvgHeartsYou.configuration.svg_paths).to eq([])
191
+ end
192
+ end