roadie 4.0.0 → 5.0.0

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