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.
- checksums.yaml +4 -4
- data/.github/workflows/main.yml +43 -0
- data/.solargraph.yml +16 -0
- data/Changelog.md +14 -2
- data/Gemfile +5 -2
- data/README.md +11 -13
- data/Rakefile +2 -2
- data/lib/roadie/asset_provider.rb +3 -1
- data/lib/roadie/asset_scanner.rb +6 -6
- data/lib/roadie/cached_provider.rb +1 -0
- data/lib/roadie/deduplicator.rb +1 -0
- data/lib/roadie/document.rb +7 -10
- data/lib/roadie/errors.rb +18 -14
- data/lib/roadie/filesystem_provider.rb +13 -3
- data/lib/roadie/inliner.rb +49 -19
- data/lib/roadie/markup_improver.rb +22 -31
- data/lib/roadie/net_http_provider.rb +25 -11
- data/lib/roadie/null_provider.rb +18 -5
- data/lib/roadie/null_url_rewriter.rb +6 -2
- data/lib/roadie/path_rewriter_provider.rb +4 -1
- data/lib/roadie/provider_list.rb +15 -11
- data/lib/roadie/rspec/asset_provider.rb +4 -1
- data/lib/roadie/rspec.rb +2 -2
- data/lib/roadie/selector.rb +15 -5
- data/lib/roadie/style_attribute_builder.rb +2 -1
- data/lib/roadie/style_block.rb +3 -3
- data/lib/roadie/style_property.rb +3 -2
- data/lib/roadie/stylesheet.rb +2 -13
- data/lib/roadie/url_generator.rb +24 -8
- data/lib/roadie/url_rewriter.rb +6 -3
- data/lib/roadie/utils.rb +1 -1
- data/lib/roadie/version.rb +1 -2
- data/lib/roadie.rb +23 -23
- data/roadie.gemspec +23 -25
- data/spec/hash_as_cache_store_spec.rb +1 -1
- data/spec/integration_spec.rb +41 -44
- data/spec/lib/roadie/asset_scanner_spec.rb +9 -4
- data/spec/lib/roadie/cached_provider_spec.rb +4 -4
- data/spec/lib/roadie/css_not_found_spec.rb +8 -5
- data/spec/lib/roadie/deduplicator_spec.rb +3 -3
- data/spec/lib/roadie/document_spec.rb +45 -27
- data/spec/lib/roadie/filesystem_provider_spec.rb +8 -10
- data/spec/lib/roadie/inliner_spec.rb +40 -44
- data/spec/lib/roadie/markup_improver_spec.rb +17 -25
- data/spec/lib/roadie/net_http_provider_spec.rb +8 -8
- data/spec/lib/roadie/null_provider_spec.rb +2 -2
- data/spec/lib/roadie/null_url_rewriter_spec.rb +2 -2
- data/spec/lib/roadie/path_rewriter_provider_spec.rb +4 -4
- data/spec/lib/roadie/provider_list_spec.rb +25 -21
- data/spec/lib/roadie/selector_spec.rb +4 -4
- data/spec/lib/roadie/style_attribute_builder_spec.rb +5 -5
- data/spec/lib/roadie/style_block_spec.rb +1 -1
- data/spec/lib/roadie/style_property_spec.rb +8 -8
- data/spec/lib/roadie/stylesheet_spec.rb +2 -20
- data/spec/lib/roadie/test_provider_spec.rb +4 -4
- data/spec/lib/roadie/url_generator_spec.rb +1 -1
- data/spec/lib/roadie/url_rewriter_spec.rb +6 -4
- data/spec/spec_helper.rb +8 -8
- data/spec/support/have_attribute_matcher.rb +1 -2
- data/spec/support/have_node_matcher.rb +3 -3
- data/spec/support/have_selector_matcher.rb +2 -3
- data/spec/support/have_styling_matcher.rb +10 -11
- data/spec/support/have_xpath_matcher.rb +2 -3
- metadata +22 -21
- data/.travis.yml +0 -20
@@ -1,11 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "spec_helper"
|
4
4
|
|
5
5
|
module Roadie
|
6
6
|
describe Inliner do
|
7
|
-
before { @stylesheet = ""
|
8
|
-
def use_css(css)
|
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
|
19
|
-
expect(rendering(
|
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
|
27
|
-
expect(rendering(
|
28
|
-
[[
|
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
|
-
[[
|
41
|
+
[["color", "blue"], ["color", "green"]]
|
40
42
|
)
|
41
43
|
end
|
42
44
|
|
43
45
|
it "inlines browser-prefixed attributes" do
|
44
|
-
use_css
|
45
|
-
expect(rendering(
|
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
|
50
|
-
expect(rendering(
|
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
|
55
|
-
expect(rendering(
|
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([[
|
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([[
|
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
|
86
|
-
rendering(
|
87
|
-
expect(document).to have_styling(
|
88
|
-
expect(document).to have_styling(
|
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
|
-
[
|
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([[
|
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
|
-
[
|
110
|
-
[
|
111
|
-
[
|
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(
|
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(
|
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
|
-
%
|
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([[
|
156
|
-
expect(result).to have_styling([[
|
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
|
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
|
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(
|
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
|
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
|
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
|
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(
|
28
|
-
expect(html.scan(
|
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(
|
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(
|
47
|
-
expect(improve(
|
48
|
-
expect(improve(
|
49
|
-
expect(improve(
|
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(
|
54
|
-
expect(improve(
|
55
|
-
expect(improve(
|
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(
|
53
|
+
dom = improve("<html><head></head><body></body></html>")
|
62
54
|
|
63
|
-
expect(dom).to have_selector(
|
64
|
-
meta = dom.at_css(
|
65
|
-
expect(meta[
|
66
|
-
expect(meta[
|
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(
|
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
|
4
|
-
require
|
5
|
-
require
|
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"
|
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
|
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
|
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,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
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(
|
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
|
4
|
-
require
|
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
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
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(
|
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
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
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
|
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(
|
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(
|
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(
|
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
|
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",
|
21
|
-
builder << StyleProperty.new("color", "red",
|
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",
|
34
|
+
builder << StyleProperty.new("color", "pink", false, 10)
|
35
35
|
builder << StyleProperty.new("color", "green", false, 20)
|
36
|
-
builder << StyleProperty.new("color", "pink",
|
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,13 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
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(
|
9
|
-
expect(declaration.property).to eq(
|
10
|
-
expect(declaration.value).to eq(
|
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(
|
19
|
-
expect(StyleProperty.new(
|
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(
|
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(
|
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
|
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}")
|