roadie 4.0.0 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/main.yml +43 -0
  3. data/.solargraph.yml +16 -0
  4. data/Changelog.md +14 -2
  5. data/Gemfile +5 -2
  6. data/README.md +11 -13
  7. data/Rakefile +2 -2
  8. data/lib/roadie/asset_provider.rb +3 -1
  9. data/lib/roadie/asset_scanner.rb +6 -6
  10. data/lib/roadie/cached_provider.rb +1 -0
  11. data/lib/roadie/deduplicator.rb +1 -0
  12. data/lib/roadie/document.rb +7 -10
  13. data/lib/roadie/errors.rb +18 -14
  14. data/lib/roadie/filesystem_provider.rb +13 -3
  15. data/lib/roadie/inliner.rb +49 -19
  16. data/lib/roadie/markup_improver.rb +22 -31
  17. data/lib/roadie/net_http_provider.rb +25 -11
  18. data/lib/roadie/null_provider.rb +18 -5
  19. data/lib/roadie/null_url_rewriter.rb +6 -2
  20. data/lib/roadie/path_rewriter_provider.rb +4 -1
  21. data/lib/roadie/provider_list.rb +15 -11
  22. data/lib/roadie/rspec/asset_provider.rb +4 -1
  23. data/lib/roadie/rspec.rb +2 -2
  24. data/lib/roadie/selector.rb +15 -5
  25. data/lib/roadie/style_attribute_builder.rb +2 -1
  26. data/lib/roadie/style_block.rb +3 -3
  27. data/lib/roadie/style_property.rb +3 -2
  28. data/lib/roadie/stylesheet.rb +2 -13
  29. data/lib/roadie/url_generator.rb +24 -8
  30. data/lib/roadie/url_rewriter.rb +6 -3
  31. data/lib/roadie/utils.rb +1 -1
  32. data/lib/roadie/version.rb +1 -2
  33. data/lib/roadie.rb +23 -23
  34. data/roadie.gemspec +23 -25
  35. data/spec/hash_as_cache_store_spec.rb +1 -1
  36. data/spec/integration_spec.rb +41 -44
  37. data/spec/lib/roadie/asset_scanner_spec.rb +9 -4
  38. data/spec/lib/roadie/cached_provider_spec.rb +4 -4
  39. data/spec/lib/roadie/css_not_found_spec.rb +8 -5
  40. data/spec/lib/roadie/deduplicator_spec.rb +3 -3
  41. data/spec/lib/roadie/document_spec.rb +45 -27
  42. data/spec/lib/roadie/filesystem_provider_spec.rb +8 -10
  43. data/spec/lib/roadie/inliner_spec.rb +40 -44
  44. data/spec/lib/roadie/markup_improver_spec.rb +17 -25
  45. data/spec/lib/roadie/net_http_provider_spec.rb +8 -8
  46. data/spec/lib/roadie/null_provider_spec.rb +2 -2
  47. data/spec/lib/roadie/null_url_rewriter_spec.rb +2 -2
  48. data/spec/lib/roadie/path_rewriter_provider_spec.rb +4 -4
  49. data/spec/lib/roadie/provider_list_spec.rb +25 -21
  50. data/spec/lib/roadie/selector_spec.rb +4 -4
  51. data/spec/lib/roadie/style_attribute_builder_spec.rb +5 -5
  52. data/spec/lib/roadie/style_block_spec.rb +1 -1
  53. data/spec/lib/roadie/style_property_spec.rb +8 -8
  54. data/spec/lib/roadie/stylesheet_spec.rb +2 -20
  55. data/spec/lib/roadie/test_provider_spec.rb +4 -4
  56. data/spec/lib/roadie/url_generator_spec.rb +1 -1
  57. data/spec/lib/roadie/url_rewriter_spec.rb +6 -4
  58. data/spec/spec_helper.rb +8 -8
  59. data/spec/support/have_attribute_matcher.rb +1 -2
  60. data/spec/support/have_node_matcher.rb +3 -3
  61. data/spec/support/have_selector_matcher.rb +2 -3
  62. data/spec/support/have_styling_matcher.rb +10 -11
  63. data/spec/support/have_xpath_matcher.rb +2 -3
  64. metadata +22 -21
  65. data/.travis.yml +0 -20
@@ -1,11 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
3
+ require "spec_helper"
4
4
 
5
5
  module Roadie
6
6
  describe Inliner do
7
- before { @stylesheet = "".freeze }
8
- def use_css(css) @stylesheet = Stylesheet.new("example", css) end
7
+ before { @stylesheet = "" }
8
+ def use_css(css)
9
+ @stylesheet = Stylesheet.new("example", css)
10
+ end
9
11
 
10
12
  def rendering(html, stylesheet = @stylesheet)
11
13
  dom = Nokogiri::HTML.parse html
@@ -15,17 +17,17 @@ module Roadie
15
17
 
16
18
  describe "inlining styles" do
17
19
  it "inlines simple attributes" do
18
- use_css 'p { color: green }'
19
- expect(rendering('<p></p>')).to have_styling('color' => 'green')
20
+ use_css "p { color: green }"
21
+ expect(rendering("<p></p>")).to have_styling("color" => "green")
20
22
  end
21
23
 
22
24
  it "keeps multiple versions of the same property to support progressive enhancement" do
23
25
  # https://github.com/premailer/css_parser/issues/44
24
26
  pending "css_parser issue #44"
25
27
 
26
- use_css 'p { color: #eee; color: rgba(255, 255, 255, 0.9); }'
27
- expect(rendering('<p></p>')).to have_styling(
28
- [['color', 'green'], ['color', 'rgba(255, 255, 255, 0.9)']]
28
+ use_css "p { color: #eee; color: rgba(255, 255, 255, 0.9); }"
29
+ expect(rendering("<p></p>")).to have_styling(
30
+ [["color", "green"], ["color", "rgba(255, 255, 255, 0.9)"]]
29
31
  )
30
32
  end
31
33
 
@@ -36,35 +38,35 @@ module Roadie
36
38
  .positive { color: green; }
37
39
  '
38
40
  expect(rendering('<p class="message positive"></p>')).to have_styling(
39
- [['color', 'blue'], ['color', 'green']]
41
+ [["color", "blue"], ["color", "green"]]
40
42
  )
41
43
  end
42
44
 
43
45
  it "inlines browser-prefixed attributes" do
44
- use_css 'p { -vendor-color: green }'
45
- expect(rendering('<p></p>')).to have_styling('-vendor-color' => 'green')
46
+ use_css "p { -vendor-color: green }"
47
+ expect(rendering("<p></p>")).to have_styling("-vendor-color" => "green")
46
48
  end
47
49
 
48
50
  it "inlines CSS3 attributes" do
49
- use_css 'p { border-radius: 2px; }'
50
- expect(rendering('<p></p>')).to have_styling('border-radius' => '2px')
51
+ use_css "p { border-radius: 2px; }"
52
+ expect(rendering("<p></p>")).to have_styling("border-radius" => "2px")
51
53
  end
52
54
 
53
55
  it "keeps the order of the styles that are inlined" do
54
- use_css 'h1 { padding: 2px; margin: 5px; }'
55
- expect(rendering('<h1></h1>')).to have_styling([['padding', '2px'], ['margin', '5px']])
56
+ use_css "h1 { padding: 2px; margin: 5px; }"
57
+ expect(rendering("<h1></h1>")).to have_styling([["padding", "2px"], ["margin", "5px"]])
56
58
  end
57
59
 
58
60
  it "combines multiple selectors into one" do
59
61
  use_css 'p { color: green; }
60
62
  .tip { float: right; }'
61
- expect(rendering('<p class="tip"></p>')).to have_styling([['color', 'green'], ['float', 'right']])
63
+ expect(rendering('<p class="tip"></p>')).to have_styling([["color", "green"], ["float", "right"]])
62
64
  end
63
65
 
64
66
  it "uses the attributes with the highest specificity when conflicts arises" do
65
67
  use_css ".safe { color: green; }
66
68
  p { color: red; }"
67
- expect(rendering('<p class="safe"></p>')).to have_styling([['color', 'red'], ['color', 'green']])
69
+ expect(rendering('<p class="safe"></p>')).to have_styling([["color", "red"], ["color", "green"]])
68
70
  end
69
71
 
70
72
  it "sorts styles by specificity order" do
@@ -82,10 +84,10 @@ module Roadie
82
84
  end
83
85
 
84
86
  it "supports multiple selectors for the same rules" do
85
- use_css 'p, a { color: green; }'
86
- rendering('<p></p><a></a>').tap do |document|
87
- expect(document).to have_styling('color' => 'green').at_selector('p')
88
- expect(document).to have_styling('color' => 'green').at_selector('a')
87
+ use_css "p, a { color: green; }"
88
+ rendering("<p></p><a></a>").tap do |document|
89
+ expect(document).to have_styling("color" => "green").at_selector("p")
90
+ expect(document).to have_styling("color" => "green").at_selector("a")
89
91
  end
90
92
  end
91
93
 
@@ -93,22 +95,22 @@ module Roadie
93
95
  use_css "a { text-decoration: underline !important; }
94
96
  a.hard-to-spot { text-decoration: none; }"
95
97
  expect(rendering('<a class="hard-to-spot"></a>')).to have_styling([
96
- ['text-decoration', 'none'], ['text-decoration', 'underline !important']
98
+ ["text-decoration", "none"], ["text-decoration", "underline !important"]
97
99
  ])
98
100
  end
99
101
 
100
102
  it "combines with already present inline styles" do
101
103
  use_css "p { color: green }"
102
- expect(rendering('<p style="font-size: 1.1em"></p>')).to have_styling([['color', 'green'], ['font-size', '1.1em']])
104
+ expect(rendering('<p style="font-size: 1.1em"></p>')).to have_styling([["color", "green"], ["font-size", "1.1em"]])
103
105
  end
104
106
 
105
107
  it "does not override inline styles" do
106
108
  use_css "p { text-transform: uppercase; color: red }"
107
109
  # The two color properties are kept to make css fallbacks work correctly
108
110
  expect(rendering('<p style="color: green"></p>')).to have_styling([
109
- ['text-transform', 'uppercase'],
110
- ['color', 'red'],
111
- ['color', 'green'],
111
+ ["text-transform", "uppercase"],
112
+ ["color", "red"],
113
+ ["color", "green"]
112
114
  ])
113
115
  end
114
116
 
@@ -123,7 +125,7 @@ module Roadie
123
125
 
124
126
  p.active { width: 100%; }
125
127
  "
126
- expect(rendering('<p class="active"></p>')).to have_styling('width' => '100%')
128
+ expect(rendering('<p class="active"></p>')).to have_styling("width" => "100%")
127
129
  end
128
130
 
129
131
  it "does not crash on any pseudo element selectors" do
@@ -131,7 +133,7 @@ module Roadie
131
133
  p.some-element { width: 100%; }
132
134
  p::some-element { color: red; }
133
135
  "
134
- expect(rendering('<p class="some-element"></p>')).to have_styling('width' => '100%')
136
+ expect(rendering('<p class="some-element"></p>')).to have_styling("width" => "100%")
135
137
  end
136
138
 
137
139
  it "warns on selectors that crash Nokogiri" do
@@ -140,7 +142,7 @@ module Roadie
140
142
  stylesheet = Stylesheet.new "foo.css", "p[%^=foo] { color: red; }"
141
143
  inliner = Inliner.new([stylesheet], dom)
142
144
  expect(Utils).to receive(:warn).with(
143
- %{Cannot inline "p[%^=foo]" from "foo.css" stylesheet. If this is valid CSS, please report a bug.}
145
+ %(Cannot inline "p[%^=foo]" from "foo.css" stylesheet. If this is valid CSS, please report a bug.)
144
146
  )
145
147
  inliner.inline
146
148
  end
@@ -152,8 +154,8 @@ module Roadie
152
154
  "
153
155
  result = rendering("<p></p> <p></p>")
154
156
 
155
- expect(result).to have_styling([['color', 'red']]).at_selector('p:first')
156
- expect(result).to have_styling([['color', 'red'], ['color', 'green']]).at_selector('p:last')
157
+ expect(result).to have_styling([["color", "red"]]).at_selector("p:first")
158
+ expect(result).to have_styling([["color", "red"], ["color", "green"]]).at_selector("p:last")
157
159
  end
158
160
 
159
161
  context "with uninlinable selectors" do
@@ -162,7 +164,7 @@ module Roadie
162
164
  end
163
165
 
164
166
  it "puts them in a new <style> element in the <head>" do
165
- use_css 'a:hover { color: red; }'
167
+ use_css "a:hover { color: red; }"
166
168
  result = rendering("
167
169
  <html>
168
170
  <head></head>
@@ -174,7 +176,7 @@ module Roadie
174
176
  end
175
177
 
176
178
  it "puts them in <head> on unexpected inlining problems" do
177
- use_css 'p:some-future-thing { color: red; }'
179
+ use_css "p:some-future-thing { color: red; }"
178
180
  result = rendering("
179
181
  <html>
180
182
  <head></head>
@@ -198,15 +200,9 @@ module Roadie
198
200
  }'
199
201
 
200
202
  use_css css
201
- result = rendering('<p></p>')
203
+ result = rendering("<p></p>")
202
204
 
203
205
  expect(result).to have_styling([]).at_selector("p")
204
-
205
- # css_parser actually sees an empty @keyframes on JRuby, and nothing
206
- # on the others
207
- if (style_element = result.at_css("head > style"))
208
- expect(style_element.text).to_not include "background-position"
209
- end
210
206
  end
211
207
 
212
208
  it "ignores them if told not to keep them" do
@@ -225,14 +221,14 @@ module Roadie
225
221
  end
226
222
 
227
223
  it "puts the <style> element at the root when told so" do
228
- stylesheet = use_css 'a:hover { color: red; }'
224
+ stylesheet = use_css "a:hover { color: red; }"
229
225
  dom = Nokogiri::HTML.fragment("
230
226
  <a></a>
231
227
  ")
232
228
 
233
229
  Inliner.new([stylesheet], dom).inline(
234
230
  keep_uninlinable_css: true,
235
- keep_uninlinable_in: :root,
231
+ keep_uninlinable_in: :root
236
232
  )
237
233
 
238
234
  expect(dom).to have_xpath("./a")
@@ -240,7 +236,7 @@ module Roadie
240
236
  end
241
237
 
242
238
  it "raises error when told to save styles in an unknown place" do
243
- stylesheet = use_css 'a:hover { color: red; }'
239
+ stylesheet = use_css "a:hover { color: red; }"
244
240
  dom = Nokogiri::HTML.fragment("
245
241
  <a></a>
246
242
  ")
@@ -249,7 +245,7 @@ module Roadie
249
245
  expect {
250
246
  inliner.inline(
251
247
  keep_uninlinable_css: true,
252
- keep_uninlinable_in: :unknown_place,
248
+ keep_uninlinable_in: :unknown_place
253
249
  )
254
250
  }.to raise_error(ArgumentError, /:unknown_place/)
255
251
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
3
+ require "spec_helper"
4
4
 
5
5
  module Roadie
6
6
  describe MarkupImprover do
@@ -10,22 +10,14 @@ module Roadie
10
10
  dom
11
11
  end
12
12
 
13
- # JRuby up to at least 1.6.0 has a bug where the doctype of a document cannot be changed.
14
- # See https://github.com/sparklemotion/nokogiri/issues/984
15
- def pending_for_buggy_jruby
16
- # No reason to check for version yet since no existing version has a fix.
17
- skip "Pending until Nokogiri issue #984 is fixed and released" if defined?(JRuby)
18
- end
19
-
20
13
  describe "automatic doctype" do
21
14
  it "inserts a HTML5 doctype if no doctype is present" do
22
- pending_for_buggy_jruby
23
15
  expect(improve("<html></html>").internal_subset.to_xml).to eq("<!DOCTYPE html>")
24
16
  end
25
17
 
26
18
  it "does not insert duplicate doctypes" do
27
- html = improve('<!DOCTYPE html><html><body></body></html>').to_html
28
- expect(html.scan('DOCTYPE').size).to eq(1)
19
+ html = improve("<!DOCTYPE html><html><body></body></html>").to_html
20
+ expect(html.scan("DOCTYPE").size).to eq(1)
29
21
  end
30
22
 
31
23
  it "leaves other doctypes alone" do
@@ -39,35 +31,35 @@ module Roadie
39
31
  it "inserts a <html> element as the root" do
40
32
  expect(improve("")).to have_selector("html")
41
33
  expect(improve("<h1>Hey!</h1>")).to have_selector("html h1")
42
- expect(improve("<html></html>").css('html').size).to eq(1)
34
+ expect(improve("<html></html>").css("html").size).to eq(1)
43
35
  end
44
36
 
45
37
  it "inserts <head> if not present" do
46
- expect(improve('<html><body></body></html>')).to have_selector('html > head + body')
47
- expect(improve('<html></html>')).to have_selector('html > head')
48
- expect(improve('Foo')).to have_selector('html > head')
49
- expect(improve('<html><head></head></html>').css('head').size).to eq(1)
38
+ expect(improve("<html><body></body></html>")).to have_selector("html > head + body")
39
+ expect(improve("<html></html>")).to have_selector("html > head")
40
+ expect(improve("Foo")).to have_selector("html > head")
41
+ expect(improve("<html><head></head></html>").css("head").size).to eq(1)
50
42
  end
51
43
 
52
44
  it "inserts <body> if not present" do
53
- expect(improve('<h1>Hey!</h1>')).to have_selector('html > body > h1')
54
- expect(improve('<html><h1>Hey!</h1></html>')).to have_selector('html > body > h1')
55
- expect(improve('<html><body><h1>Hey!</h1></body></html>').css('body').size).to eq(1)
45
+ expect(improve("<h1>Hey!</h1>")).to have_selector("html > body > h1")
46
+ expect(improve("<html><h1>Hey!</h1></html>")).to have_selector("html > body > h1")
47
+ expect(improve("<html><body><h1>Hey!</h1></body></html>").css("body").size).to eq(1)
56
48
  end
57
49
  end
58
50
 
59
51
  describe "charset declaration" do
60
52
  it "is inserted if missing" do
61
- dom = improve('<html><head></head><body></body></html>')
53
+ dom = improve("<html><head></head><body></body></html>")
62
54
 
63
- expect(dom).to have_selector('head meta')
64
- meta = dom.at_css('head meta')
65
- expect(meta['http-equiv']).to eq('Content-Type')
66
- expect(meta['content']).to eq('text/html; charset=UTF-8')
55
+ expect(dom).to have_selector("head meta")
56
+ meta = dom.at_css("head meta")
57
+ expect(meta["http-equiv"]).to eq("Content-Type")
58
+ expect(meta["content"]).to eq("text/html; charset=UTF-8")
67
59
  end
68
60
 
69
61
  it "is left alone when predefined" do
70
- expect(improve(<<-HTML).xpath('//meta')).to have(1).item
62
+ expect(improve(<<-HTML).xpath("//meta")).to have(1).item
71
63
  <html>
72
64
  <head>
73
65
  <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
- require 'roadie/rspec'
5
- require 'shared_examples/asset_provider'
3
+ require "spec_helper"
4
+ require "roadie/rspec"
5
+ require "shared_examples/asset_provider"
6
6
 
7
7
  module Roadie
8
8
  describe NetHttpProvider do
@@ -12,7 +12,7 @@ module Roadie
12
12
  WebMock.allow_net_connect!
13
13
  end
14
14
 
15
- url = "http://example.com/style.css".freeze
15
+ url = "http://example.com/style.css"
16
16
 
17
17
  it_behaves_like(
18
18
  "roadie asset provider",
@@ -51,7 +51,7 @@ module Roadie
51
51
  # use when trying to make sense of these bytes.
52
52
  stub_request(:get, url).and_return(
53
53
  body: (+%(p::before { content: "l\xF6ve" })).force_encoding("US-ASCII"),
54
- headers: {"Content-Type" => "text/css;charset=ISO-8859-1"},
54
+ headers: {"Content-Type" => "text/css;charset=ISO-8859-1"}
55
55
  )
56
56
 
57
57
  # Seems like CssParser strips out the non-ascii character for some
@@ -67,7 +67,7 @@ module Roadie
67
67
  it "assumes UTF-8 encoding if server headers do not specify a charset" do
68
68
  stub_request(:get, url).and_return(
69
69
  body: (+%(p::before { content: "Åh nej" })).force_encoding("US-ASCII"),
70
- headers: {"Content-Type" => "text/css"},
70
+ headers: {"Content-Type" => "text/css"}
71
71
  )
72
72
 
73
73
  # Seems like CssParser strips out the non-ascii characters for some
@@ -119,10 +119,10 @@ module Roadie
119
119
  provider = NetHttpProvider.new(whitelist: ["whitelisted.example.com"])
120
120
 
121
121
  whitelisted_url = "http://whitelisted.example.com/style.css"
122
- other_url = "http://www.example.com/style.css"
122
+ other_url = "http://www.example.com/style.css"
123
123
 
124
124
  whitelisted_request = stub_request(:get, whitelisted_url).and_return(body: +"x")
125
- other_request = stub_request(:get, other_url).and_return(body: +"x")
125
+ other_request = stub_request(:get, other_url).and_return(body: +"x")
126
126
 
127
127
  expect(provider.find_stylesheet(other_url)).to be_nil
128
128
  expect {
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
- require 'shared_examples/asset_provider'
3
+ require "spec_helper"
4
+ require "shared_examples/asset_provider"
5
5
 
6
6
  module Roadie
7
7
  describe NullProvider do
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
- require 'shared_examples/url_rewriter'
3
+ require "spec_helper"
4
+ require "shared_examples/url_rewriter"
5
5
 
6
6
  module Roadie
7
7
  describe NullUrlRewriter do
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
- require 'roadie/rspec'
5
- require 'shared_examples/asset_provider'
3
+ require "spec_helper"
4
+ require "roadie/rspec"
5
+ require "shared_examples/asset_provider"
6
6
 
7
7
  module Roadie
8
8
  describe PathRewriterProvider do
@@ -10,7 +10,7 @@ module Roadie
10
10
 
11
11
  subject(:provider) do
12
12
  PathRewriterProvider.new(upstream) do |path|
13
- path.gsub('well', 'good')
13
+ path.gsub("well", "good")
14
14
  end
15
15
  end
16
16
 
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
- require 'roadie/rspec'
3
+ require "spec_helper"
4
+ require "roadie/rspec"
5
5
 
6
6
  module Roadie
7
7
  describe ProviderList do
@@ -69,36 +69,40 @@ module Roadie
69
69
  provider = double("Provider", to_s: "Some provider")
70
70
  sublist = ProviderList.new([provider, provider])
71
71
  list = ProviderList.new([provider, sublist, provider])
72
- expect(list.to_s).to eql(
73
- "ProviderList: [\n" +
74
- "\tSome provider,\n" +
75
- "\tProviderList: [\n" +
76
- "\t\tSome provider,\n" +
77
- "\t\tSome provider\n" +
78
- "\t],\n" +
79
- "\tSome provider\n" +
80
- "]"
81
- )
72
+ expect(list.to_s).to eq(<<~TEXT)
73
+ ProviderList: [
74
+ \tSome provider,
75
+ \tProviderList: [
76
+ \t\tSome provider,
77
+ \t\tSome provider
78
+ \t],
79
+ \tSome provider
80
+ ]
81
+ TEXT
82
82
  end
83
83
 
84
84
  it "raises a readable error message" do
85
85
  provider = double("Provider", to_s: "Some provider")
86
86
  allow(provider).to receive(:find_stylesheet!).and_raise(
87
- CssNotFound.new("style.css", "I tripped", provider)
87
+ CssNotFound.new(
88
+ css_name: "style.css",
89
+ message: "I tripped",
90
+ provider: provider
91
+ )
88
92
  )
89
93
 
90
94
  sublist = ProviderList.new([provider, provider])
91
95
  list = ProviderList.new([provider, sublist, provider])
92
96
 
93
97
  expect { list.find_stylesheet!("style.css") }.to raise_error { |error|
94
- expect(error.message).to eq(
95
- "Could not find stylesheet \"style.css\": All providers failed\n" +
96
- "Used providers:\n" +
97
- "\tSome provider: I tripped\n" +
98
- "\tSome provider: I tripped\n" +
99
- "\tSome provider: I tripped\n" +
100
- "\tSome provider: I tripped\n"
101
- )
98
+ expect(error.message).to eq(<<~TEXT)
99
+ Could not find stylesheet "style.css": All providers failed
100
+ Used providers:
101
+ \tSome provider: I tripped
102
+ \tSome provider: I tripped
103
+ \tSome provider: I tripped
104
+ \tSome provider: I tripped
105
+ TEXT
102
106
  }
103
107
  end
104
108
 
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
3
+ require "spec_helper"
4
4
 
5
5
  module Roadie
6
6
  describe Selector do
@@ -31,15 +31,15 @@ module Roadie
31
31
  expect(Selector.new(bad_selector)).not_to be_inlinable
32
32
  end
33
33
 
34
- expect(Selector.new('p.active')).to be_inlinable
34
+ expect(Selector.new("p.active")).to be_inlinable
35
35
  end
36
36
 
37
37
  it "cannot be inlined when containing pseudo elements" do
38
- expect(Selector.new('p::some-element')).not_to be_inlinable
38
+ expect(Selector.new("p::some-element")).not_to be_inlinable
39
39
  end
40
40
 
41
41
  it "cannot be inlined when selector is an at-rule" do
42
- expect(Selector.new('@keyframes progress-bar-stripes')).not_to be_inlinable
42
+ expect(Selector.new("@keyframes progress-bar-stripes")).not_to be_inlinable
43
43
  end
44
44
 
45
45
  it "has a calculated specificity" do
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
3
+ require "spec_helper"
4
4
 
5
5
  module Roadie
6
6
  describe StyleAttributeBuilder do
@@ -17,8 +17,8 @@ module Roadie
17
17
  it "preserves the order of added attributes with the same specificity" do
18
18
  builder = StyleAttributeBuilder.new
19
19
 
20
- builder << StyleProperty.new("color", "pink", false, 50)
21
- builder << StyleProperty.new("color", "red", false, 50)
20
+ builder << StyleProperty.new("color", "pink", false, 50)
21
+ builder << StyleProperty.new("color", "red", false, 50)
22
22
  builder << StyleProperty.new("color", "green", false, 50)
23
23
 
24
24
  # We need one different element to trigger the problem with Ruby's
@@ -31,9 +31,9 @@ module Roadie
31
31
  it "removes duplicate properties" do
32
32
  builder = StyleAttributeBuilder.new
33
33
 
34
- builder << StyleProperty.new("color", "pink", false, 10)
34
+ builder << StyleProperty.new("color", "pink", false, 10)
35
35
  builder << StyleProperty.new("color", "green", false, 20)
36
- builder << StyleProperty.new("color", "pink", false, 50)
36
+ builder << StyleProperty.new("color", "pink", false, 50)
37
37
 
38
38
  expect(builder.attribute_string).to eq "color:green;color:pink"
39
39
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
3
+ require "spec_helper"
4
4
 
5
5
  module Roadie
6
6
  describe StyleBlock do
@@ -1,13 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
3
+ require "spec_helper"
4
4
 
5
5
  module Roadie
6
6
  describe StyleProperty do
7
7
  it "is initialized with a property, value, if it is marked as important, and the specificity" do
8
- StyleProperty.new('color', 'green', true, 45).tap do |declaration|
9
- expect(declaration.property).to eq('color')
10
- expect(declaration.value).to eq('green')
8
+ StyleProperty.new("color", "green", true, 45).tap do |declaration|
9
+ expect(declaration.property).to eq("color")
10
+ expect(declaration.value).to eq("green")
11
11
  expect(declaration).to be_important
12
12
  expect(declaration.specificity).to eq(45)
13
13
  end
@@ -15,18 +15,18 @@ module Roadie
15
15
 
16
16
  describe "string representation" do
17
17
  it "is the property and the value joined with a colon" do
18
- expect(StyleProperty.new('color', 'green', false, 1).to_s).to eq('color:green')
19
- expect(StyleProperty.new('font-size', '1.1em', false, 1).to_s).to eq('font-size:1.1em')
18
+ expect(StyleProperty.new("color", "green", false, 1).to_s).to eq("color:green")
19
+ expect(StyleProperty.new("font-size", "1.1em", false, 1).to_s).to eq("font-size:1.1em")
20
20
  end
21
21
 
22
22
  it "contains the !important flag when set" do
23
- expect(StyleProperty.new('color', 'green', true, 1).to_s).to eq('color:green !important')
23
+ expect(StyleProperty.new("color", "green", true, 1).to_s).to eq("color:green !important")
24
24
  end
25
25
  end
26
26
 
27
27
  describe "comparing" do
28
28
  def declaration(specificity, important = false)
29
- StyleProperty.new('color', 'green', important, specificity)
29
+ StyleProperty.new("color", "green", important, specificity)
30
30
  end
31
31
 
32
32
  it "compares on specificity" do
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
3
+ require "spec_helper"
4
4
 
5
5
  module Roadie
6
6
  describe Stylesheet do
@@ -18,28 +18,10 @@ module Roadie
18
18
  expect(stylesheet.blocks.map(&:to_s)).to eq([
19
19
  "body{color:green !important;font-size:200%}",
20
20
  "a{color:red}",
21
- "i{color:red}",
21
+ "i{color:red}"
22
22
  ])
23
23
  end
24
24
 
25
- if VERSION < "4.0"
26
- it "can iterate all inlinable blocks" do
27
- inlinable = double(inlinable?: true, selector: "good", properties: "props")
28
- bad = double(inlinable?: false, selector: "bad", properties: "props")
29
-
30
- stylesheet = Stylesheet.new("example.css", "")
31
- allow(stylesheet).to receive_messages blocks: [bad, inlinable, bad]
32
-
33
- expect(stylesheet.each_inlinable_block.to_a).to eq([
34
- ["good", "props"],
35
- ])
36
- end
37
- else
38
- it "should no longer have #each_inlinable_block" do
39
- fail "Remove #each_inlinable_block"
40
- end
41
- end
42
-
43
25
  it "has a string representation of the contents" do
44
26
  stylesheet = Stylesheet.new("example.css", "body { color: green;}a{ color: red; font-size: small }")
45
27
  expect(stylesheet.to_s).to eq("body{color:green}\na{color:red;font-size:small}")