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
@@ -1,11 +1,13 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
2
4
|
|
3
5
|
module Roadie
|
4
6
|
describe StyleProperty do
|
5
7
|
it "is initialized with a property, value, if it is marked as important, and the specificity" do
|
6
|
-
StyleProperty.new(
|
7
|
-
expect(declaration.property).to eq(
|
8
|
-
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")
|
9
11
|
expect(declaration).to be_important
|
10
12
|
expect(declaration.specificity).to eq(45)
|
11
13
|
end
|
@@ -13,18 +15,18 @@ module Roadie
|
|
13
15
|
|
14
16
|
describe "string representation" do
|
15
17
|
it "is the property and the value joined with a colon" do
|
16
|
-
expect(StyleProperty.new(
|
17
|
-
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")
|
18
20
|
end
|
19
21
|
|
20
22
|
it "contains the !important flag when set" do
|
21
|
-
expect(StyleProperty.new(
|
23
|
+
expect(StyleProperty.new("color", "green", true, 1).to_s).to eq("color:green !important")
|
22
24
|
end
|
23
25
|
end
|
24
26
|
|
25
27
|
describe "comparing" do
|
26
28
|
def declaration(specificity, important = false)
|
27
|
-
StyleProperty.new(
|
29
|
+
StyleProperty.new("color", "green", important, specificity)
|
28
30
|
end
|
29
31
|
|
30
32
|
it "compares on specificity" do
|
@@ -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 Stylesheet do
|
@@ -17,28 +18,10 @@ module Roadie
|
|
17
18
|
expect(stylesheet.blocks.map(&:to_s)).to eq([
|
18
19
|
"body{color:green !important;font-size:200%}",
|
19
20
|
"a{color:red}",
|
20
|
-
"i{color:red}"
|
21
|
+
"i{color:red}"
|
21
22
|
])
|
22
23
|
end
|
23
24
|
|
24
|
-
if VERSION < "4.0"
|
25
|
-
it "can iterate all inlinable blocks" do
|
26
|
-
inlinable = double(inlinable?: true, selector: "good", properties: "props")
|
27
|
-
bad = double(inlinable?: false, selector: "bad", properties: "props")
|
28
|
-
|
29
|
-
stylesheet = Stylesheet.new("example.css", "")
|
30
|
-
allow(stylesheet).to receive_messages blocks: [bad, inlinable, bad]
|
31
|
-
|
32
|
-
expect(stylesheet.each_inlinable_block.to_a).to eq([
|
33
|
-
["good", "props"],
|
34
|
-
])
|
35
|
-
end
|
36
|
-
else
|
37
|
-
it "should no longer have #each_inlinable_block" do
|
38
|
-
fail "Remove #each_inlinable_block"
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
25
|
it "has a string representation of the contents" do
|
43
26
|
stylesheet = Stylesheet.new("example.css", "body { color: green;}a{ color: red; font-size: small }")
|
44
27
|
expect(stylesheet.to_s).to eq("body{color:green}\na{color:red;font-size:small}")
|
@@ -1,5 +1,7 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
require "roadie/rspec"
|
3
5
|
|
4
6
|
describe TestProvider do
|
5
7
|
subject(:provider) { TestProvider.new }
|
@@ -11,7 +13,7 @@ describe TestProvider do
|
|
11
13
|
it "finds styles from a predefined hash" do
|
12
14
|
provider = TestProvider.new({
|
13
15
|
"foo.css" => "a { color: red; }",
|
14
|
-
"bar.css" => "body { color: green; }"
|
16
|
+
"bar.css" => "body { color: green; }"
|
15
17
|
})
|
16
18
|
expect(provider.find_stylesheet("foo.css").to_s).not_to include("body")
|
17
19
|
expect(provider.find_stylesheet("bar.css").to_s).to include("body")
|
@@ -21,7 +23,7 @@ describe TestProvider do
|
|
21
23
|
it "can have a default for missing entries" do
|
22
24
|
provider = TestProvider.new({
|
23
25
|
"foo.css" => "a { color: red; }",
|
24
|
-
:default
|
26
|
+
:default => "body { color: green; }"
|
25
27
|
})
|
26
28
|
expect(provider.find_stylesheet("foo.css").to_s).not_to include("body")
|
27
29
|
expect(provider.find_stylesheet("bar.css").to_s).to include("body")
|
@@ -1,5 +1,7 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
require "shared_examples/url_rewriter"
|
3
5
|
|
4
6
|
module Roadie
|
5
7
|
describe UrlRewriter do
|
@@ -9,7 +11,9 @@ module Roadie
|
|
9
11
|
it_behaves_like "url rewriter"
|
10
12
|
|
11
13
|
describe "transforming DOM trees" do
|
12
|
-
def dom_document(html)
|
14
|
+
def dom_document(html)
|
15
|
+
Nokogiri::HTML.parse html
|
16
|
+
end
|
13
17
|
|
14
18
|
it "rewrites all a[href]" do
|
15
19
|
expect(generator).to receive(:generate_url).with("some/path").and_return "http://foo.com/"
|
@@ -71,9 +75,8 @@ module Roadie
|
|
71
75
|
it "rewrites all url() directives" do
|
72
76
|
expect(generator).to receive(:generate_url).with("some/path.jpg").and_return "http://foo.com/image.jpg"
|
73
77
|
css = "body { background: top url(some/path.jpg) #eee; }"
|
74
|
-
|
75
|
-
|
76
|
-
}.to change { css }.to "body { background: top url(http://foo.com/image.jpg) #eee; }"
|
78
|
+
transformed_css = rewriter.transform_css css
|
79
|
+
expect(transformed_css).to eq "body { background: top url(http://foo.com/image.jpg) #eee; }"
|
77
80
|
end
|
78
81
|
|
79
82
|
it "correctly identifies URLs with single quotes" do
|
@@ -88,7 +91,7 @@ module Roadie
|
|
88
91
|
|
89
92
|
it "correctly identifies URLs with parenthesis inside them" do
|
90
93
|
expect(generator).to receive(:generate_url).with("images/map_(large_(extra)).png").and_return "x"
|
91
|
-
rewriter.transform_css
|
94
|
+
rewriter.transform_css "url(images/map_(large_(extra)).png)"
|
92
95
|
end
|
93
96
|
end
|
94
97
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
shared_examples_for "url rewriter" do
|
2
4
|
it "is constructed with a generator" do
|
3
5
|
generator = double "URL generator"
|
@@ -6,7 +8,7 @@ shared_examples_for "url rewriter" do
|
|
6
8
|
}.to_not raise_error
|
7
9
|
end
|
8
10
|
|
9
|
-
it "has a #transform_dom(dom) method that returns
|
11
|
+
it "has a #transform_dom(dom) method that returns the modified string" do
|
10
12
|
expect(subject).to respond_to(:transform_dom)
|
11
13
|
expect(subject.method(:transform_dom).arity).to eq(1)
|
12
14
|
|
@@ -14,10 +16,10 @@ shared_examples_for "url rewriter" do
|
|
14
16
|
expect(subject.transform_dom(dom)).to be_nil
|
15
17
|
end
|
16
18
|
|
17
|
-
it "has a #transform_css(css) method that returns
|
19
|
+
it "has a #transform_css(css) method that returns the modified string" do
|
18
20
|
expect(subject).to respond_to(:transform_css)
|
19
21
|
expect(subject.method(:transform_css).arity).to eq(1)
|
20
22
|
|
21
|
-
expect(subject.transform_css("")).to
|
23
|
+
expect(subject.transform_css("")).to eq("")
|
22
24
|
end
|
23
25
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,19 +1,21 @@
|
|
1
|
-
|
2
|
-
require 'webmock/rspec'
|
1
|
+
# frozen_string_literal: true
|
3
2
|
|
4
|
-
|
5
|
-
|
3
|
+
require "rspec/collection_matchers"
|
4
|
+
require "webmock/rspec"
|
5
|
+
|
6
|
+
if ENV["CI"]
|
7
|
+
require "simplecov"
|
6
8
|
SimpleCov.start
|
7
9
|
|
8
|
-
require
|
10
|
+
require "codecov"
|
9
11
|
SimpleCov.formatter = SimpleCov::Formatter::Codecov
|
10
12
|
end
|
11
13
|
|
12
|
-
$: << File.dirname(__FILE__) +
|
13
|
-
require
|
14
|
+
$: << File.dirname(__FILE__) + "/../lib"
|
15
|
+
require "roadie"
|
14
16
|
|
15
17
|
RSpec.configure do |config|
|
16
18
|
config.run_all_when_everything_filtered = true
|
17
19
|
end
|
18
20
|
|
19
|
-
Dir[
|
21
|
+
Dir["./spec/support/**/*.rb"].sort.each { |file| require file }
|
@@ -1,5 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
RSpec::Matchers.define :have_attribute do |attribute|
|
2
|
-
@selector =
|
4
|
+
@selector = "body > *:first"
|
3
5
|
|
4
6
|
chain :at_selector do |selector|
|
5
7
|
@selector = selector
|
@@ -25,4 +27,3 @@ RSpec::Matchers.define :have_attribute do |attribute|
|
|
25
27
|
node && node[attribute_name]
|
26
28
|
end
|
27
29
|
end
|
28
|
-
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
RSpec::Matchers.define :have_node do |selector|
|
2
4
|
chain(:with_attributes) { |attributes| @attributes = attributes }
|
3
5
|
match do |document|
|
@@ -9,11 +11,11 @@ RSpec::Matchers.define :have_node do |selector|
|
|
9
11
|
end
|
10
12
|
end
|
11
13
|
|
12
|
-
failure_message { "expected document to #{name_to_sentence}#{expected_to_sentence}"}
|
13
|
-
failure_message_when_negated { "expected document to not #{name_to_sentence}#{expected_to_sentence}"}
|
14
|
+
failure_message { "expected document to #{name_to_sentence}#{expected_to_sentence}" }
|
15
|
+
failure_message_when_negated { "expected document to not #{name_to_sentence}#{expected_to_sentence}" }
|
14
16
|
|
15
17
|
def match_attributes(node_attributes)
|
16
|
-
attributes =
|
18
|
+
attributes = node_attributes.map { |name, attribute| [name, attribute.value] }.to_h
|
17
19
|
@attributes == attributes
|
18
20
|
end
|
19
21
|
end
|
@@ -1,6 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
RSpec::Matchers.define :have_selector do |selector|
|
2
4
|
match { |document| !document.css(selector).empty? }
|
3
|
-
failure_message { "expected document to have selector #{selector.inspect}"}
|
4
|
-
failure_message_when_negated { "expected document to not have selector #{selector.inspect}"}
|
5
|
+
failure_message { "expected document to have selector #{selector.inspect}" }
|
6
|
+
failure_message_when_negated { "expected document to not have selector #{selector.inspect}" }
|
5
7
|
end
|
6
|
-
|
@@ -1,9 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
RSpec::Matchers.define :have_styling do |rules|
|
2
4
|
normalized_rules = StylingExpectation.new(rules)
|
3
5
|
|
4
6
|
chain(:at_selector) { |selector| @selector = selector }
|
5
7
|
match { |document|
|
6
|
-
@selector ||=
|
8
|
+
@selector ||= "body > *:first"
|
7
9
|
normalized_rules == styles_at_selector(document)
|
8
10
|
}
|
9
11
|
|
@@ -21,7 +23,7 @@ RSpec::Matchers.define :have_styling do |rules|
|
|
21
23
|
|
22
24
|
def styles_at_selector(document)
|
23
25
|
expect(document).to have_selector(@selector)
|
24
|
-
StylingExpectation.new document.at_css(@selector)[
|
26
|
+
StylingExpectation.new document.at_css(@selector)["style"]
|
25
27
|
end
|
26
28
|
end
|
27
29
|
|
@@ -40,23 +42,22 @@ class StylingExpectation
|
|
40
42
|
rules == other.rules
|
41
43
|
end
|
42
44
|
|
43
|
-
def to_s
|
45
|
+
def to_s
|
46
|
+
rules.to_s
|
47
|
+
end
|
44
48
|
|
45
49
|
protected
|
50
|
+
|
46
51
|
attr_reader :rules
|
47
52
|
|
48
53
|
private
|
54
|
+
|
49
55
|
def parse_rules(css)
|
50
|
-
css.split(
|
56
|
+
css.split(";").map { |property| parse_property(property) }
|
51
57
|
end
|
52
58
|
|
53
59
|
def parse_property(property)
|
54
|
-
rule, value = property.split(
|
55
|
-
[rule,
|
56
|
-
end
|
57
|
-
|
58
|
-
# JRuby's Nokogiri encodes quotes
|
59
|
-
def normalize_quotes(string)
|
60
|
-
string.gsub '%22', '"'
|
60
|
+
rule, value = property.split(":", 2).map(&:strip)
|
61
|
+
[rule, value]
|
61
62
|
end
|
62
63
|
end
|
@@ -1,6 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
RSpec::Matchers.define :have_xpath do |xpath|
|
2
4
|
match { |document| !document.xpath(xpath).empty? }
|
3
|
-
failure_message { "expected document to have xpath #{xpath.inspect}"}
|
4
|
-
failure_message_when_negated { "expected document to not have xpath #{xpath.inspect}"}
|
5
|
+
failure_message { "expected document to have xpath #{xpath.inspect}" }
|
6
|
+
failure_message_when_negated { "expected document to not have xpath #{xpath.inspect}" }
|
5
7
|
end
|
6
|
-
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: roadie
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 5.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Magnus Bergmark
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-05-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '1.4'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: rspec
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -91,8 +105,10 @@ extra_rdoc_files:
|
|
91
105
|
- Changelog.md
|
92
106
|
files:
|
93
107
|
- ".autotest"
|
108
|
+
- ".github/workflows/main.yml"
|
94
109
|
- ".gitignore"
|
95
|
-
- ".
|
110
|
+
- ".rubocop.yml"
|
111
|
+
- ".solargraph.yml"
|
96
112
|
- ".yardopts"
|
97
113
|
- Changelog.md
|
98
114
|
- Gemfile
|
@@ -166,7 +182,7 @@ homepage: http://github.com/Mange/roadie
|
|
166
182
|
licenses:
|
167
183
|
- MIT
|
168
184
|
metadata: {}
|
169
|
-
post_install_message:
|
185
|
+
post_install_message:
|
170
186
|
rdoc_options: []
|
171
187
|
require_paths:
|
172
188
|
- lib
|
@@ -174,15 +190,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
174
190
|
requirements:
|
175
191
|
- - ">="
|
176
192
|
- !ruby/object:Gem::Version
|
177
|
-
version: '
|
193
|
+
version: '2.6'
|
178
194
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
179
195
|
requirements:
|
180
196
|
- - ">="
|
181
197
|
- !ruby/object:Gem::Version
|
182
198
|
version: '0'
|
183
199
|
requirements: []
|
184
|
-
rubygems_version: 3.0.
|
185
|
-
signing_key:
|
200
|
+
rubygems_version: 3.0.9
|
201
|
+
signing_key:
|
186
202
|
specification_version: 4
|
187
203
|
summary: Making HTML emails comfortable for the Ruby rockstars
|
188
204
|
test_files:
|
data/.travis.yml
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
sudo: false
|
2
|
-
language: ruby
|
3
|
-
rvm:
|
4
|
-
- 2.1
|
5
|
-
- 2.2
|
6
|
-
- 2.3
|
7
|
-
- 2.4
|
8
|
-
- 2.5
|
9
|
-
- jruby
|
10
|
-
- rbx
|
11
|
-
before_install:
|
12
|
-
- gem install bundler -v '1.17.3'
|
13
|
-
matrix:
|
14
|
-
allow_failures:
|
15
|
-
# Rubinius and JRuby have a lot of trouble and no large following, so I'm going to
|
16
|
-
# allow failures on it until it gets more stable on Travis / Real Life(tm).
|
17
|
-
# Let me know if you need it. Patches are welcome!
|
18
|
-
- rvm: jruby
|
19
|
-
- rvm: rbx
|
20
|
-
fast_finish: true
|
21
|
-
cache: bundler
|
22
|
-
script: "rake"
|