roadie 3.5.1 → 5.0.1
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/.rubocop.yml +5 -0
- data/.solargraph.yml +16 -0
- data/Changelog.md +30 -4
- data/Gemfile +7 -2
- data/README.md +12 -14
- data/Rakefile +4 -3
- data/lib/roadie/asset_provider.rb +5 -1
- data/lib/roadie/asset_scanner.rb +8 -6
- data/lib/roadie/cached_provider.rb +3 -0
- data/lib/roadie/deduplicator.rb +3 -0
- data/lib/roadie/document.rb +10 -11
- data/lib/roadie/errors.rb +22 -16
- data/lib/roadie/filesystem_provider.rb +15 -3
- data/lib/roadie/inliner.rb +51 -19
- data/lib/roadie/markup_improver.rb +24 -31
- data/lib/roadie/net_http_provider.rb +27 -12
- data/lib/roadie/null_provider.rb +20 -5
- data/lib/roadie/null_url_rewriter.rb +11 -3
- data/lib/roadie/path_rewriter_provider.rb +6 -1
- data/lib/roadie/provider_list.rb +17 -11
- data/lib/roadie/rspec/asset_provider.rb +6 -1
- data/lib/roadie/rspec/cache_store.rb +2 -0
- data/lib/roadie/rspec.rb +4 -2
- data/lib/roadie/selector.rb +18 -5
- data/lib/roadie/style_attribute_builder.rb +4 -1
- data/lib/roadie/style_block.rb +5 -3
- data/lib/roadie/style_property.rb +5 -2
- data/lib/roadie/stylesheet.rb +4 -13
- data/lib/roadie/url_generator.rb +26 -8
- data/lib/roadie/url_rewriter.rb +12 -9
- data/lib/roadie/utils.rb +3 -1
- data/lib/roadie/version.rb +1 -1
- data/lib/roadie.rb +25 -23
- data/roadie.gemspec +23 -23
- data/spec/hash_as_cache_store_spec.rb +3 -1
- data/spec/integration_spec.rb +43 -44
- data/spec/lib/roadie/asset_scanner_spec.rb +11 -5
- data/spec/lib/roadie/cached_provider_spec.rb +6 -4
- data/spec/lib/roadie/css_not_found_spec.rb +10 -5
- data/spec/lib/roadie/deduplicator_spec.rb +5 -3
- data/spec/lib/roadie/document_spec.rb +47 -28
- data/spec/lib/roadie/filesystem_provider_spec.rb +10 -11
- data/spec/lib/roadie/inliner_spec.rb +42 -45
- data/spec/lib/roadie/markup_improver_spec.rb +19 -26
- data/spec/lib/roadie/net_http_provider_spec.rb +16 -14
- data/spec/lib/roadie/null_provider_spec.rb +4 -3
- data/spec/lib/roadie/null_url_rewriter_spec.rb +4 -3
- data/spec/lib/roadie/path_rewriter_provider_spec.rb +6 -4
- data/spec/lib/roadie/provider_list_spec.rb +27 -22
- data/spec/lib/roadie/selector_spec.rb +7 -5
- data/spec/lib/roadie/style_attribute_builder_spec.rb +7 -5
- data/spec/lib/roadie/style_block_spec.rb +3 -2
- data/spec/lib/roadie/style_property_spec.rb +10 -8
- data/spec/lib/roadie/stylesheet_spec.rb +4 -21
- data/spec/lib/roadie/test_provider_spec.rb +6 -4
- data/spec/lib/roadie/url_generator_spec.rb +3 -2
- data/spec/lib/roadie/url_rewriter_spec.rb +10 -7
- data/spec/lib/roadie/utils_spec.rb +2 -0
- data/spec/shared_examples/asset_provider.rb +2 -0
- data/spec/shared_examples/url_rewriter.rb +5 -3
- data/spec/spec_helper.rb +10 -8
- data/spec/support/have_attribute_matcher.rb +3 -2
- data/spec/support/have_node_matcher.rb +5 -3
- data/spec/support/have_selector_matcher.rb +4 -3
- data/spec/support/have_styling_matcher.rb +12 -11
- data/spec/support/have_xpath_matcher.rb +4 -3
- data/spec/support/test_provider.rb +2 -0
- metadata +24 -8
- data/.travis.yml +0 -22
data/lib/roadie/version.rb
CHANGED
data/lib/roadie.rb
CHANGED
@@ -1,30 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Roadie
|
2
4
|
end
|
3
5
|
|
4
|
-
require
|
5
|
-
require
|
6
|
+
require "roadie/version"
|
7
|
+
require "roadie/errors"
|
6
8
|
|
7
|
-
require
|
8
|
-
require
|
9
|
+
require "roadie/utils"
|
10
|
+
require "roadie/deduplicator"
|
9
11
|
|
10
|
-
require
|
11
|
-
require
|
12
|
-
require
|
13
|
-
require
|
14
|
-
require
|
12
|
+
require "roadie/stylesheet"
|
13
|
+
require "roadie/selector"
|
14
|
+
require "roadie/style_property"
|
15
|
+
require "roadie/style_attribute_builder"
|
16
|
+
require "roadie/style_block"
|
15
17
|
|
16
|
-
require
|
17
|
-
require
|
18
|
-
require
|
19
|
-
require
|
20
|
-
require
|
21
|
-
require
|
22
|
-
require
|
18
|
+
require "roadie/asset_provider"
|
19
|
+
require "roadie/provider_list"
|
20
|
+
require "roadie/filesystem_provider"
|
21
|
+
require "roadie/null_provider"
|
22
|
+
require "roadie/net_http_provider"
|
23
|
+
require "roadie/cached_provider"
|
24
|
+
require "roadie/path_rewriter_provider"
|
23
25
|
|
24
|
-
require
|
25
|
-
require
|
26
|
-
require
|
27
|
-
require
|
28
|
-
require
|
29
|
-
require
|
30
|
-
require
|
26
|
+
require "roadie/asset_scanner"
|
27
|
+
require "roadie/markup_improver"
|
28
|
+
require "roadie/url_generator"
|
29
|
+
require "roadie/url_rewriter"
|
30
|
+
require "roadie/null_url_rewriter"
|
31
|
+
require "roadie/inliner"
|
32
|
+
require "roadie/document"
|
data/roadie.gemspec
CHANGED
@@ -1,33 +1,33 @@
|
|
1
1
|
# roadie.gemspec
|
2
|
-
#
|
2
|
+
# frozen_string_literal: true
|
3
3
|
|
4
4
|
$:.push File.expand_path("../lib", __FILE__)
|
5
|
-
require
|
5
|
+
require "roadie/version"
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
|
-
s.name
|
9
|
-
s.version
|
10
|
-
s.platform
|
11
|
-
s.authors
|
12
|
-
s.email
|
13
|
-
s.homepage
|
14
|
-
s.summary
|
15
|
-
s.description =
|
16
|
-
s.license
|
17
|
-
|
18
|
-
s.required_ruby_version = ">=
|
19
|
-
|
20
|
-
s.add_dependency
|
21
|
-
s.add_dependency
|
22
|
-
|
23
|
-
s.add_development_dependency
|
24
|
-
s.add_development_dependency
|
25
|
-
s.add_development_dependency
|
8
|
+
s.name = "roadie"
|
9
|
+
s.version = Roadie::VERSION
|
10
|
+
s.platform = Gem::Platform::RUBY
|
11
|
+
s.authors = ["Magnus Bergmark"]
|
12
|
+
s.email = ["magnus.bergmark@gmail.com"]
|
13
|
+
s.homepage = "http://github.com/Mange/roadie"
|
14
|
+
s.summary = "Making HTML emails comfortable for the Ruby rockstars"
|
15
|
+
s.description = "Roadie tries to make sending HTML emails a little less painful by inlining stylesheets and rewriting relative URLs for you."
|
16
|
+
s.license = "MIT"
|
17
|
+
|
18
|
+
s.required_ruby_version = ">= 2.6"
|
19
|
+
|
20
|
+
s.add_dependency "nokogiri", "~> 1.8"
|
21
|
+
s.add_dependency "css_parser", "~> 1.4"
|
22
|
+
|
23
|
+
s.add_development_dependency "rake"
|
24
|
+
s.add_development_dependency "rspec", "~> 3.0"
|
25
|
+
s.add_development_dependency "rspec-collection_matchers", "~> 1.0"
|
26
|
+
s.add_development_dependency "webmock", "~> 3.0"
|
26
27
|
|
27
28
|
s.extra_rdoc_files = %w[README.md Changelog.md]
|
28
29
|
s.require_paths = %w[lib]
|
29
30
|
|
30
|
-
s.files
|
31
|
-
s.test_files
|
31
|
+
s.files = `git ls-files`.split("\n")
|
32
|
+
s.test_files = `git ls-files -- spec/*`.split("\n")
|
32
33
|
end
|
33
|
-
|
data/spec/integration_spec.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
2
4
|
|
3
5
|
describe "Roadie functionality" do
|
4
6
|
describe "on full documents" do
|
@@ -11,14 +13,7 @@ describe "Roadie functionality" do
|
|
11
13
|
document = Roadie::Document.new(html)
|
12
14
|
result = document.transform
|
13
15
|
|
14
|
-
|
15
|
-
# JRuby has a bug that makes DTD manipulation impossible
|
16
|
-
# See Nokogiri bugs #984 and #985
|
17
|
-
# https://github.com/sparklemotion/nokogiri/issues/984
|
18
|
-
# https://github.com/sparklemotion/nokogiri/issues/985
|
19
|
-
expect(result).to include("<!DOCTYPE html>")
|
20
|
-
end
|
21
|
-
|
16
|
+
expect(result).to include("<!DOCTYPE html>")
|
22
17
|
expect(result).to include("<html>")
|
23
18
|
expect(result).to include("<head>")
|
24
19
|
expect(result).to include("<body>")
|
@@ -45,8 +40,8 @@ describe "Roadie functionality" do
|
|
45
40
|
CSS
|
46
41
|
|
47
42
|
result = parse_html document.transform
|
48
|
-
expect(result).to have_styling(
|
49
|
-
expect(result).to have_styling(
|
43
|
+
expect(result).to have_styling("text-align" => "center").at_selector("h1")
|
44
|
+
expect(result).to have_styling("color" => "red").at_selector("p > em")
|
50
45
|
end
|
51
46
|
|
52
47
|
it "stores styles that cannot be inlined in the <head>" do
|
@@ -110,7 +105,7 @@ describe "Roadie functionality" do
|
|
110
105
|
HTML
|
111
106
|
|
112
107
|
result = parse_html document.transform
|
113
|
-
expect(result).to have_styling(
|
108
|
+
expect(result).to have_styling("font-size" => "200%").at_selector("p > em")
|
114
109
|
end
|
115
110
|
|
116
111
|
it "crashes when stylesheets cannot be found, unless using NullProvider" do
|
@@ -125,7 +120,9 @@ describe "Roadie functionality" do
|
|
125
120
|
</html>
|
126
121
|
HTML
|
127
122
|
|
128
|
-
expect {
|
123
|
+
expect {
|
124
|
+
document.transform
|
125
|
+
}.to raise_error(Roadie::CssNotFound, /does_not_exist\.css/)
|
129
126
|
|
130
127
|
document.asset_providers << Roadie::NullProvider.new
|
131
128
|
expect { document.transform }.to_not raise_error
|
@@ -149,8 +146,8 @@ describe "Roadie functionality" do
|
|
149
146
|
document.external_asset_providers = []
|
150
147
|
|
151
148
|
result = parse_html document.transform
|
152
|
-
expect(result).to have_selector(
|
153
|
-
expect(result).to have_styling([]).at_selector(
|
149
|
+
expect(result).to have_selector("head > link")
|
150
|
+
expect(result).to have_styling([]).at_selector("p > em")
|
154
151
|
end
|
155
152
|
|
156
153
|
it "inlines external css if configured" do
|
@@ -173,8 +170,8 @@ describe "Roadie functionality" do
|
|
173
170
|
)
|
174
171
|
|
175
172
|
result = parse_html document.transform
|
176
|
-
expect(result).to have_styling(
|
177
|
-
expect(result).to_not have_selector(
|
173
|
+
expect(result).to have_styling("font-size" => "200%").at_selector("p > em")
|
174
|
+
expect(result).to_not have_selector("head > link")
|
178
175
|
end
|
179
176
|
|
180
177
|
it "does not inline the same properties several times" do
|
@@ -195,8 +192,8 @@ describe "Roadie functionality" do
|
|
195
192
|
|
196
193
|
result = parse_html document.transform
|
197
194
|
expect(result).to have_styling([
|
198
|
-
[
|
199
|
-
]).at_selector(
|
195
|
+
["color", "red"]
|
196
|
+
]).at_selector("p")
|
200
197
|
end
|
201
198
|
|
202
199
|
it "makes URLs absolute" do
|
@@ -230,7 +227,7 @@ describe "Roadie functionality" do
|
|
230
227
|
).at_selector("body")
|
231
228
|
|
232
229
|
expect(result).to have_styling(
|
233
|
-
"background" =>
|
230
|
+
"background" => "url(https://myapp.com/rails/app/assets/link-abcdef1234567890.png)"
|
234
231
|
).at_selector("a")
|
235
232
|
end
|
236
233
|
|
@@ -322,10 +319,10 @@ describe "Roadie functionality" do
|
|
322
319
|
)
|
323
320
|
|
324
321
|
result = parse_html document.transform
|
325
|
-
expect(result).to have_styling(
|
322
|
+
expect(result).to have_styling("color" => "green").at_selector(".colorful")
|
326
323
|
end
|
327
324
|
|
328
|
-
it
|
325
|
+
it "puts non-inlineable media queries in the head" do
|
329
326
|
document = Roadie::Document.new <<-HTML
|
330
327
|
<html>
|
331
328
|
<head>
|
@@ -351,18 +348,18 @@ describe "Roadie functionality" do
|
|
351
348
|
|
352
349
|
result = parse_html document.transform
|
353
350
|
|
354
|
-
styles = result.at_css(
|
351
|
+
styles = result.at_css("html > head > style").text
|
355
352
|
expected_result = <<-CSS
|
356
353
|
@media screen and (max-width 800px) { .colorful{color:blue} }
|
357
354
|
@media screen, print and (max-width 800px) { .colorful{color:blue} }
|
358
355
|
CSS
|
359
|
-
expected_result = expected_result.gsub(
|
360
|
-
actual_result = styles.gsub(
|
356
|
+
expected_result = expected_result.gsub(/\s+/, " ").strip
|
357
|
+
actual_result = styles.gsub(/\s+/, " ").strip
|
361
358
|
|
362
359
|
expect(actual_result).to eq(expected_result)
|
363
360
|
end
|
364
361
|
|
365
|
-
it
|
362
|
+
it "groups non-inlineable media queries in the head by default" do
|
366
363
|
document = Roadie::Document.new <<-HTML
|
367
364
|
<html>
|
368
365
|
<head>
|
@@ -388,20 +385,20 @@ describe "Roadie functionality" do
|
|
388
385
|
|
389
386
|
result = parse_html document.transform
|
390
387
|
|
391
|
-
styles = result.at_css(
|
388
|
+
styles = result.at_css("html > head > style").text
|
392
389
|
expected_result = <<-CSS
|
393
390
|
@media screen and (max-width 600px) {
|
394
391
|
.colorful{color:red;width:600px}
|
395
392
|
.colorful-2{color:red;width:600px}
|
396
393
|
}
|
397
394
|
CSS
|
398
|
-
expected_result = expected_result.gsub(
|
399
|
-
actual_result = styles.gsub(
|
395
|
+
expected_result = expected_result.gsub(/\s+/, " ").strip
|
396
|
+
actual_result = styles.gsub(/\s+/, " ").strip
|
400
397
|
|
401
398
|
expect(actual_result).to eq(expected_result)
|
402
399
|
end
|
403
400
|
|
404
|
-
describe
|
401
|
+
describe "if merge_media_queries is set to false" do
|
405
402
|
it "doesn't group non-inlineable media queries in the head" do
|
406
403
|
document = Roadie::Document.new <<-HTML
|
407
404
|
<html>
|
@@ -430,7 +427,7 @@ describe "Roadie functionality" do
|
|
430
427
|
|
431
428
|
result = parse_html document.transform
|
432
429
|
|
433
|
-
styles = result.at_css(
|
430
|
+
styles = result.at_css("html > head > style").text
|
434
431
|
expected_result = <<-CSS
|
435
432
|
@media screen and (max-width 600px) {
|
436
433
|
.colorful{color:red;width:600px}
|
@@ -439,8 +436,8 @@ describe "Roadie functionality" do
|
|
439
436
|
.colorful-2{color:red;width:600px}
|
440
437
|
}
|
441
438
|
CSS
|
442
|
-
expected_result = expected_result.gsub(
|
443
|
-
actual_result = styles.gsub(
|
439
|
+
expected_result = expected_result.gsub(/\s+/, " ").strip
|
440
|
+
actual_result = styles.gsub(/\s+/, " ").strip
|
444
441
|
|
445
442
|
expect(actual_result).to eq(expected_result)
|
446
443
|
end
|
@@ -472,8 +469,8 @@ describe "Roadie functionality" do
|
|
472
469
|
CSS
|
473
470
|
|
474
471
|
result = parse_html document.transform_partial
|
475
|
-
expect(result).to have_styling(
|
476
|
-
expect(result).to have_styling(
|
472
|
+
expect(result).to have_styling("text-align" => "center").at_selector("h1")
|
473
|
+
expect(result).to have_styling("color" => "red").at_selector("p > em")
|
477
474
|
end
|
478
475
|
|
479
476
|
it "stores styles that cannot be inlined in a new <style> element" do
|
@@ -521,7 +518,7 @@ describe "Roadie functionality" do
|
|
521
518
|
HTML
|
522
519
|
|
523
520
|
result = parse_html document.transform_partial
|
524
|
-
expect(result).to have_styling(
|
521
|
+
expect(result).to have_styling("font-size" => "200%").at_selector("p > em")
|
525
522
|
end
|
526
523
|
|
527
524
|
it "crashes when stylesheets cannot be found, unless using NullProvider" do
|
@@ -529,7 +526,9 @@ describe "Roadie functionality" do
|
|
529
526
|
<link rel="stylesheet" href="/spec/fixtures/does_not_exist.css">
|
530
527
|
HTML
|
531
528
|
|
532
|
-
expect {
|
529
|
+
expect {
|
530
|
+
document.transform_partial
|
531
|
+
}.to raise_error(Roadie::CssNotFound, /does_not_exist\.css/)
|
533
532
|
|
534
533
|
document.asset_providers << Roadie::NullProvider.new
|
535
534
|
expect { document.transform_partial }.to_not raise_error
|
@@ -545,8 +544,8 @@ describe "Roadie functionality" do
|
|
545
544
|
document.external_asset_providers = []
|
546
545
|
|
547
546
|
result = parse_html document.transform_partial
|
548
|
-
expect(result).to have_xpath(
|
549
|
-
expect(result).to have_styling([]).at_selector(
|
547
|
+
expect(result).to have_xpath("./link")
|
548
|
+
expect(result).to have_styling([]).at_selector("p > em")
|
550
549
|
end
|
551
550
|
|
552
551
|
it "inlines external css if configured" do
|
@@ -561,8 +560,8 @@ describe "Roadie functionality" do
|
|
561
560
|
)
|
562
561
|
|
563
562
|
result = parse_html document.transform_partial
|
564
|
-
expect(result).to have_styling(
|
565
|
-
expect(result).to_not have_xpath(
|
563
|
+
expect(result).to have_styling("font-size" => "200%").at_selector("p > em")
|
564
|
+
expect(result).to_not have_xpath("./link")
|
566
565
|
end
|
567
566
|
|
568
567
|
it "does not inline the same properties several times" do
|
@@ -579,8 +578,8 @@ describe "Roadie functionality" do
|
|
579
578
|
|
580
579
|
result = parse_html document.transform_partial
|
581
580
|
expect(result).to have_styling([
|
582
|
-
[
|
583
|
-
]).at_selector(
|
581
|
+
["color", "red"]
|
582
|
+
]).at_selector("p")
|
584
583
|
end
|
585
584
|
|
586
585
|
it "makes URLs absolute" do
|
@@ -613,7 +612,7 @@ describe "Roadie functionality" do
|
|
613
612
|
).at_selector("div")
|
614
613
|
|
615
614
|
expect(result).to have_styling(
|
616
|
-
"background" =>
|
615
|
+
"background" => "url(https://myapp.com/rails/app/assets/link-abcdef1234567890.png)"
|
617
616
|
).at_selector("a")
|
618
617
|
end
|
619
618
|
|
@@ -1,5 +1,6 @@
|
|
1
|
-
#
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
3
4
|
|
4
5
|
module Roadie
|
5
6
|
describe AssetScanner do
|
@@ -7,8 +8,13 @@ module Roadie
|
|
7
8
|
let(:external_provider) { ProviderList.empty }
|
8
9
|
let(:dom) { dom_document "<html></html>" }
|
9
10
|
|
10
|
-
def dom_fragment(html)
|
11
|
-
|
11
|
+
def dom_fragment(html)
|
12
|
+
Nokogiri::HTML.fragment html
|
13
|
+
end
|
14
|
+
|
15
|
+
def dom_document(html)
|
16
|
+
Nokogiri::HTML.parse html
|
17
|
+
end
|
12
18
|
|
13
19
|
it "is initialized with a DOM tree, a normal asset provider set, and an external asset provider set" do
|
14
20
|
scanner = AssetScanner.new dom, normal_provider, external_provider
|
@@ -110,7 +116,7 @@ module Roadie
|
|
110
116
|
expect(scanner.find_css).to eq([])
|
111
117
|
end
|
112
118
|
|
113
|
-
it
|
119
|
+
it "ignores HTML comments and CDATA sections" do
|
114
120
|
# TinyMCE posts invalid CSS. We support that just to be pragmatic.
|
115
121
|
dom = dom_fragment %(<style><![CDATA[
|
116
122
|
<!--
|
@@ -1,11 +1,13 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
require "roadie/rspec"
|
5
|
+
require "shared_examples/asset_provider"
|
4
6
|
|
5
7
|
module Roadie
|
6
8
|
describe CachedProvider do
|
7
9
|
let(:upstream) { TestProvider.new("good.css" => "body { color: green; }") }
|
8
|
-
let(:cache) {
|
10
|
+
let(:cache) { {} }
|
9
11
|
subject(:provider) { CachedProvider.new(upstream, cache) }
|
10
12
|
|
11
13
|
it_behaves_like "roadie asset provider", valid_name: "good.css", invalid_name: "bad.css"
|
@@ -1,22 +1,27 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
2
4
|
|
3
5
|
module Roadie
|
4
6
|
describe CssNotFound do
|
5
7
|
it "is initialized with a name" do
|
6
|
-
error = CssNotFound.new(
|
7
|
-
expect(error.css_name).to eq(
|
8
|
+
error = CssNotFound.new(css_name: "style.css")
|
9
|
+
expect(error.css_name).to eq("style.css")
|
8
10
|
expect(error.message).to eq('Could not find stylesheet "style.css"')
|
9
11
|
end
|
10
12
|
|
11
13
|
it "can be initialized with an extra message" do
|
12
|
-
|
14
|
+
error = CssNotFound.new(css_name: "file.css", message: "directory is missing")
|
15
|
+
expect(error.message).to eq(
|
13
16
|
'Could not find stylesheet "file.css": directory is missing'
|
14
17
|
)
|
15
18
|
end
|
16
19
|
|
17
20
|
it "shows information about used provider when given" do
|
18
21
|
provider = double("Some cool provider")
|
19
|
-
|
22
|
+
error = CssNotFound.new(css_name: "style.css", provider: provider)
|
23
|
+
|
24
|
+
expect(error.message).to eq(
|
20
25
|
%(Could not find stylesheet "style.css"\nUsed provider:\n#{provider})
|
21
26
|
)
|
22
27
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "spec_helper"
|
2
4
|
|
3
5
|
module Roadie
|
@@ -7,13 +9,13 @@ module Roadie
|
|
7
9
|
["a", "1"],
|
8
10
|
["b", "2"],
|
9
11
|
["a", "3"],
|
10
|
-
["a", "1"]
|
12
|
+
["a", "1"]
|
11
13
|
]
|
12
14
|
|
13
15
|
expect(Deduplicator.apply(input)).to eq [
|
14
16
|
["b", "2"],
|
15
17
|
["a", "3"],
|
16
|
-
["a", "1"]
|
18
|
+
["a", "1"]
|
17
19
|
]
|
18
20
|
end
|
19
21
|
|
@@ -21,7 +23,7 @@ module Roadie
|
|
21
23
|
input = [
|
22
24
|
["a", "1"],
|
23
25
|
["a", "3"],
|
24
|
-
["a", "2"]
|
26
|
+
["a", "2"]
|
25
27
|
]
|
26
28
|
|
27
29
|
expect(Deduplicator.apply(input)).to eq input
|
@@ -1,5 +1,6 @@
|
|
1
|
-
#
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
3
4
|
|
4
5
|
module Roadie
|
5
6
|
describe Document do
|
@@ -69,6 +70,9 @@ module Roadie
|
|
69
70
|
|
70
71
|
document.mode = :html
|
71
72
|
expect(document.mode).to eq(:html)
|
73
|
+
|
74
|
+
document.mode = :xml
|
75
|
+
expect(document.mode).to eq(:xml)
|
72
76
|
end
|
73
77
|
|
74
78
|
it "does not allow unknown modes" do
|
@@ -90,8 +94,8 @@ module Roadie
|
|
90
94
|
describe "transforming" do
|
91
95
|
it "runs the before and after callbacks" do
|
92
96
|
document = Document.new "<body></body>"
|
93
|
-
before = ->{}
|
94
|
-
after = ->{}
|
97
|
+
before = -> {}
|
98
|
+
after = -> {}
|
95
99
|
document.before_transformation = before
|
96
100
|
document.after_transformation = after
|
97
101
|
|
@@ -102,21 +106,6 @@ module Roadie
|
|
102
106
|
document.transform
|
103
107
|
end
|
104
108
|
|
105
|
-
# TODO: Remove on next major version.
|
106
|
-
it "works on callables that don't expect more than one argument" do
|
107
|
-
document = Document.new "<body></body>"
|
108
|
-
document.before_transformation = ->(first) { }
|
109
|
-
document.after_transformation = ->(first = nil) { }
|
110
|
-
|
111
|
-
expect { document.transform }.to_not raise_error
|
112
|
-
|
113
|
-
# It still supplies the second argument, if possible.
|
114
|
-
document.after_transformation = ->(first, second = nil) {
|
115
|
-
raise "Oops" unless second
|
116
|
-
}
|
117
|
-
expect { document.transform }.to_not raise_error
|
118
|
-
end
|
119
|
-
|
120
109
|
context "in HTML mode" do
|
121
110
|
it "does not escape curly braces" do
|
122
111
|
document = Document.new "<body><a href='https://google.com/{{hello}}'>Hello</a></body>"
|
@@ -125,26 +114,41 @@ module Roadie
|
|
125
114
|
expect(document.transform).to include("{{hello}}")
|
126
115
|
end
|
127
116
|
end
|
117
|
+
|
118
|
+
context "in XML mode" do
|
119
|
+
it "doesn't replace empty tags with self-closed ones" do
|
120
|
+
document = Document.new "<img src='https://google.com/image.png'></img>"
|
121
|
+
document.mode = :xml
|
122
|
+
|
123
|
+
expect(document.transform_partial).to end_with("</img>")
|
124
|
+
end
|
125
|
+
|
126
|
+
it "does not escape curly braces" do
|
127
|
+
document = Document.new "<a href='https://google.com/{{hello}}'>Hello</a>"
|
128
|
+
document.mode = :xml
|
129
|
+
expect(document.transform_partial).to include("{{hello}}")
|
130
|
+
end
|
131
|
+
end
|
128
132
|
end
|
129
133
|
|
130
134
|
describe "partial transforming" do
|
131
135
|
it "runs the before and after callbacks" do
|
132
136
|
document = Document.new "<p></p>"
|
133
|
-
before = ->{}
|
134
|
-
after = ->{}
|
137
|
+
before = -> {}
|
138
|
+
after = -> {}
|
135
139
|
document.before_transformation = before
|
136
140
|
document.after_transformation = after
|
137
141
|
|
138
142
|
expect(before).to receive(:call).with(
|
139
143
|
instance_of(Nokogiri::HTML::DocumentFragment),
|
140
|
-
document
|
144
|
+
document
|
141
145
|
).ordered
|
142
146
|
|
143
147
|
expect(Inliner).to receive(:new).ordered.and_return double.as_null_object
|
144
148
|
|
145
149
|
expect(after).to receive(:call).with(
|
146
150
|
instance_of(Nokogiri::HTML::DocumentFragment),
|
147
|
-
document
|
151
|
+
document
|
148
152
|
).ordered
|
149
153
|
|
150
154
|
document.transform_partial
|
@@ -158,6 +162,21 @@ module Roadie
|
|
158
162
|
expect(document.transform_partial).to include("{{hello}}")
|
159
163
|
end
|
160
164
|
end
|
165
|
+
|
166
|
+
context "in XML mode" do
|
167
|
+
it "doesn't replace empty tags with self-closed ones" do
|
168
|
+
document = Document.new "<img src='https://google.com/image.png'></img>"
|
169
|
+
document.mode = :xml
|
170
|
+
|
171
|
+
expect(document.transform_partial).to end_with("</img>")
|
172
|
+
end
|
173
|
+
|
174
|
+
it "does not escape curly braces" do
|
175
|
+
document = Document.new "<a href='https://google.com/{{hello}}'>Hello</a>"
|
176
|
+
document.mode = :xml
|
177
|
+
expect(document.transform_partial).to include("{{hello}}")
|
178
|
+
end
|
179
|
+
end
|
161
180
|
end
|
162
181
|
end
|
163
182
|
|
@@ -178,11 +197,11 @@ module Roadie
|
|
178
197
|
|
179
198
|
result = Nokogiri::HTML.parse document.transform
|
180
199
|
|
181
|
-
expect(result).to have_selector(
|
182
|
-
expect(result.at_css(
|
200
|
+
expect(result).to have_selector("html > head > title")
|
201
|
+
expect(result.at_css("title").text).to eq("Greetings")
|
183
202
|
|
184
|
-
expect(result).to have_selector(
|
185
|
-
paragraph = result.at_css(
|
203
|
+
expect(result).to have_selector("html > body > p")
|
204
|
+
paragraph = result.at_css("p")
|
186
205
|
expect(paragraph.text).to eq("Hello, world!")
|
187
206
|
expect(paragraph.to_xml).to eq('<p style="color:green">Hello, world!</p>')
|
188
207
|
end
|
@@ -201,7 +220,7 @@ module Roadie
|
|
201
220
|
HTML
|
202
221
|
|
203
222
|
document.asset_providers = TestProvider.new({
|
204
|
-
"/sample.css" => "p { color: red; text-align: right; }"
|
223
|
+
"/sample.css" => "p { color: red; text-align: right; }"
|
205
224
|
})
|
206
225
|
|
207
226
|
document.add_css "p { color: green; text-size: 2em; }"
|