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.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/main.yml +43 -0
  3. data/.rubocop.yml +5 -0
  4. data/.solargraph.yml +16 -0
  5. data/Changelog.md +30 -4
  6. data/Gemfile +7 -2
  7. data/README.md +12 -14
  8. data/Rakefile +4 -3
  9. data/lib/roadie/asset_provider.rb +5 -1
  10. data/lib/roadie/asset_scanner.rb +8 -6
  11. data/lib/roadie/cached_provider.rb +3 -0
  12. data/lib/roadie/deduplicator.rb +3 -0
  13. data/lib/roadie/document.rb +10 -11
  14. data/lib/roadie/errors.rb +22 -16
  15. data/lib/roadie/filesystem_provider.rb +15 -3
  16. data/lib/roadie/inliner.rb +51 -19
  17. data/lib/roadie/markup_improver.rb +24 -31
  18. data/lib/roadie/net_http_provider.rb +27 -12
  19. data/lib/roadie/null_provider.rb +20 -5
  20. data/lib/roadie/null_url_rewriter.rb +11 -3
  21. data/lib/roadie/path_rewriter_provider.rb +6 -1
  22. data/lib/roadie/provider_list.rb +17 -11
  23. data/lib/roadie/rspec/asset_provider.rb +6 -1
  24. data/lib/roadie/rspec/cache_store.rb +2 -0
  25. data/lib/roadie/rspec.rb +4 -2
  26. data/lib/roadie/selector.rb +18 -5
  27. data/lib/roadie/style_attribute_builder.rb +4 -1
  28. data/lib/roadie/style_block.rb +5 -3
  29. data/lib/roadie/style_property.rb +5 -2
  30. data/lib/roadie/stylesheet.rb +4 -13
  31. data/lib/roadie/url_generator.rb +26 -8
  32. data/lib/roadie/url_rewriter.rb +12 -9
  33. data/lib/roadie/utils.rb +3 -1
  34. data/lib/roadie/version.rb +1 -1
  35. data/lib/roadie.rb +25 -23
  36. data/roadie.gemspec +23 -23
  37. data/spec/hash_as_cache_store_spec.rb +3 -1
  38. data/spec/integration_spec.rb +43 -44
  39. data/spec/lib/roadie/asset_scanner_spec.rb +11 -5
  40. data/spec/lib/roadie/cached_provider_spec.rb +6 -4
  41. data/spec/lib/roadie/css_not_found_spec.rb +10 -5
  42. data/spec/lib/roadie/deduplicator_spec.rb +5 -3
  43. data/spec/lib/roadie/document_spec.rb +47 -28
  44. data/spec/lib/roadie/filesystem_provider_spec.rb +10 -11
  45. data/spec/lib/roadie/inliner_spec.rb +42 -45
  46. data/spec/lib/roadie/markup_improver_spec.rb +19 -26
  47. data/spec/lib/roadie/net_http_provider_spec.rb +16 -14
  48. data/spec/lib/roadie/null_provider_spec.rb +4 -3
  49. data/spec/lib/roadie/null_url_rewriter_spec.rb +4 -3
  50. data/spec/lib/roadie/path_rewriter_provider_spec.rb +6 -4
  51. data/spec/lib/roadie/provider_list_spec.rb +27 -22
  52. data/spec/lib/roadie/selector_spec.rb +7 -5
  53. data/spec/lib/roadie/style_attribute_builder_spec.rb +7 -5
  54. data/spec/lib/roadie/style_block_spec.rb +3 -2
  55. data/spec/lib/roadie/style_property_spec.rb +10 -8
  56. data/spec/lib/roadie/stylesheet_spec.rb +4 -21
  57. data/spec/lib/roadie/test_provider_spec.rb +6 -4
  58. data/spec/lib/roadie/url_generator_spec.rb +3 -2
  59. data/spec/lib/roadie/url_rewriter_spec.rb +10 -7
  60. data/spec/lib/roadie/utils_spec.rb +2 -0
  61. data/spec/shared_examples/asset_provider.rb +2 -0
  62. data/spec/shared_examples/url_rewriter.rb +5 -3
  63. data/spec/spec_helper.rb +10 -8
  64. data/spec/support/have_attribute_matcher.rb +3 -2
  65. data/spec/support/have_node_matcher.rb +5 -3
  66. data/spec/support/have_selector_matcher.rb +4 -3
  67. data/spec/support/have_styling_matcher.rb +12 -11
  68. data/spec/support/have_xpath_matcher.rb +4 -3
  69. data/spec/support/test_provider.rb +2 -0
  70. metadata +24 -8
  71. data/.travis.yml +0 -22
@@ -1,11 +1,13 @@
1
- require 'spec_helper'
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('color', 'green', true, 45).tap do |declaration|
7
- expect(declaration.property).to eq('color')
8
- 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")
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('color', 'green', false, 1).to_s).to eq('color:green')
17
- 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")
18
20
  end
19
21
 
20
22
  it "contains the !important flag when set" do
21
- 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")
22
24
  end
23
25
  end
24
26
 
25
27
  describe "comparing" do
26
28
  def declaration(specificity, important = false)
27
- StyleProperty.new('color', 'green', important, specificity)
29
+ StyleProperty.new("color", "green", important, specificity)
28
30
  end
29
31
 
30
32
  it "compares on specificity" do
@@ -1,5 +1,6 @@
1
- # encoding: UTF-8
2
- require 'spec_helper'
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
- require 'spec_helper'
2
- require 'roadie/rspec'
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 => "body { color: green; }",
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,6 @@
1
- # encoding: UTF-8
2
- require 'spec_helper'
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
3
4
 
4
5
  module Roadie
5
6
  describe UrlGenerator do
@@ -1,5 +1,7 @@
1
- require 'spec_helper'
2
- require 'shared_examples/url_rewriter'
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); Nokogiri::HTML.parse html; end
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
- expect {
75
- rewriter.transform_css css
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 'url(images/map_(large_(extra)).png)'
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
  require "spec_helper"
2
4
 
3
5
  module Roadie
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  shared_examples_for "asset provider role" do
2
4
  it "responds to #find_stylesheet" do
3
5
  expect(subject).to respond_to(:find_stylesheet)
@@ -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 nil" do
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 nil" do
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 be_nil
23
+ expect(subject.transform_css("")).to eq("")
22
24
  end
23
25
  end
data/spec/spec_helper.rb CHANGED
@@ -1,19 +1,21 @@
1
- require 'rspec/collection_matchers'
2
- require 'webmock/rspec'
1
+ # frozen_string_literal: true
3
2
 
4
- if ENV['CI']
5
- require 'simplecov'
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 'codecov'
10
+ require "codecov"
9
11
  SimpleCov.formatter = SimpleCov::Formatter::Codecov
10
12
  end
11
13
 
12
- $: << File.dirname(__FILE__) + '/../lib'
13
- require 'roadie'
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['./spec/support/**/*.rb'].each { |file| require file }
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 = 'body > *:first'
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 = Hash[node_attributes.map { |name, attribute| [name, attribute.value] }]
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 ||= 'body > *:first'
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)['style']
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() rules.to_s end
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(';').map { |property| parse_property(property) }
56
+ css.split(";").map { |property| parse_property(property) }
51
57
  end
52
58
 
53
59
  def parse_property(property)
54
- rule, value = property.split(':', 2).map(&:strip)
55
- [rule, normalize_quotes(value)]
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
-
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class TestProvider
2
4
  include Roadie::AssetProvider
3
5
 
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: 3.5.1
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: 2019-10-02 00:00:00.000000000 Z
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
- - ".travis.yml"
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: '1.9'
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.2
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"