roadie 2.4.3 → 3.0.0.pre1
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 +7 -0
- data/.gitignore +3 -0
- data/.travis.yml +9 -14
- data/.yardopts +1 -1
- data/Changelog.md +22 -10
- data/Gemfile +3 -0
- data/Guardfile +11 -1
- data/README.md +165 -163
- data/Rakefile +2 -19
- data/lib/roadie.rb +14 -69
- data/lib/roadie/asset_provider.rb +7 -58
- data/lib/roadie/asset_scanner.rb +92 -0
- data/lib/roadie/document.rb +103 -0
- data/lib/roadie/errors.rb +57 -0
- data/lib/roadie/filesystem_provider.rb +21 -62
- data/lib/roadie/inliner.rb +71 -218
- data/lib/roadie/markup_improver.rb +88 -0
- data/lib/roadie/null_provider.rb +13 -0
- data/lib/roadie/null_url_rewriter.rb +12 -0
- data/lib/roadie/provider_list.rb +67 -0
- data/lib/roadie/rspec.rb +1 -0
- data/lib/roadie/rspec/asset_provider.rb +49 -0
- data/lib/roadie/selector.rb +42 -18
- data/lib/roadie/style_block.rb +33 -0
- data/lib/roadie/style_properties.rb +29 -0
- data/lib/roadie/style_property.rb +93 -0
- data/lib/roadie/stylesheet.rb +65 -0
- data/lib/roadie/url_generator.rb +126 -0
- data/lib/roadie/url_rewriter.rb +84 -0
- data/lib/roadie/version.rb +1 -1
- data/roadie.gemspec +6 -10
- data/spec/fixtures/big_em.css +1 -0
- data/spec/fixtures/stylesheets/green.css +1 -0
- data/spec/integration_spec.rb +125 -95
- data/spec/lib/roadie/asset_scanner_spec.rb +153 -0
- data/spec/lib/roadie/css_not_found_spec.rb +16 -0
- data/spec/lib/roadie/document_spec.rb +123 -0
- data/spec/lib/roadie/filesystem_provider_spec.rb +25 -72
- data/spec/lib/roadie/inliner_spec.rb +105 -537
- data/spec/lib/roadie/markup_improver_spec.rb +78 -0
- data/spec/lib/roadie/null_provider_spec.rb +21 -0
- data/spec/lib/roadie/null_url_rewriter_spec.rb +19 -0
- data/spec/lib/roadie/provider_list_spec.rb +81 -0
- data/spec/lib/roadie/selector_spec.rb +7 -5
- data/spec/lib/roadie/style_block_spec.rb +35 -0
- data/spec/lib/roadie/style_properties_spec.rb +61 -0
- data/spec/lib/roadie/style_property_spec.rb +82 -0
- data/spec/lib/roadie/stylesheet_spec.rb +41 -0
- data/spec/lib/roadie/test_provider_spec.rb +29 -0
- data/spec/lib/roadie/url_generator_spec.rb +120 -0
- data/spec/lib/roadie/url_rewriter_spec.rb +79 -0
- data/spec/shared_examples/asset_provider.rb +11 -0
- data/spec/shared_examples/url_rewriter.rb +23 -0
- data/spec/spec_helper.rb +5 -60
- data/spec/support/have_node_matcher.rb +2 -2
- data/spec/support/have_selector_matcher.rb +1 -1
- data/spec/support/have_styling_matcher.rb +48 -14
- data/spec/support/test_provider.rb +13 -0
- metadata +73 -177
- data/Appraisals +0 -15
- data/gemfiles/rails_3.0.gemfile +0 -7
- data/gemfiles/rails_3.0.gemfile.lock +0 -123
- data/gemfiles/rails_3.1.gemfile +0 -7
- data/gemfiles/rails_3.1.gemfile.lock +0 -126
- data/gemfiles/rails_3.2.gemfile +0 -7
- data/gemfiles/rails_3.2.gemfile.lock +0 -124
- data/gemfiles/rails_4.0.gemfile +0 -7
- data/gemfiles/rails_4.0.gemfile.lock +0 -119
- data/lib/roadie/action_mailer_extensions.rb +0 -95
- data/lib/roadie/asset_pipeline_provider.rb +0 -28
- data/lib/roadie/css_file_not_found.rb +0 -22
- data/lib/roadie/railtie.rb +0 -39
- data/lib/roadie/style_declaration.rb +0 -42
- data/spec/fixtures/app/assets/stylesheets/integration.css +0 -10
- data/spec/fixtures/public/stylesheets/integration.css +0 -10
- data/spec/fixtures/views/integration_mailer/marketing.html.erb +0 -2
- data/spec/fixtures/views/integration_mailer/notification.html.erb +0 -8
- data/spec/fixtures/views/integration_mailer/notification.text.erb +0 -6
- data/spec/lib/roadie/action_mailer_extensions_spec.rb +0 -227
- data/spec/lib/roadie/asset_pipeline_provider_spec.rb +0 -65
- data/spec/lib/roadie/css_file_not_found_spec.rb +0 -29
- data/spec/lib/roadie/style_declaration_spec.rb +0 -49
- data/spec/lib/roadie_spec.rb +0 -101
- data/spec/shared_examples/asset_provider_examples.rb +0 -11
- data/spec/support/anonymous_mailer.rb +0 -21
- data/spec/support/change_url_options.rb +0 -5
- data/spec/support/parse_styling.rb +0 -25
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'roadie/rspec'
|
3
|
+
|
4
|
+
describe TestProvider do
|
5
|
+
subject(:provider) { TestProvider.new }
|
6
|
+
|
7
|
+
it_behaves_like "roadie asset provider", valid_name: "existing.css", invalid_name: "invalid.css" do
|
8
|
+
subject { TestProvider.new "existing.css" => "" }
|
9
|
+
end
|
10
|
+
|
11
|
+
it "finds styles from a predefined hash" do
|
12
|
+
provider = TestProvider.new({
|
13
|
+
"foo.css" => "a { color: red; }",
|
14
|
+
"bar.css" => "body { color: green; }",
|
15
|
+
})
|
16
|
+
provider.find_stylesheet("foo.css").to_s.should_not include("body")
|
17
|
+
provider.find_stylesheet("bar.css").to_s.should include("body")
|
18
|
+
provider.find_stylesheet("baz.css").should be_nil
|
19
|
+
end
|
20
|
+
|
21
|
+
it "can have a default for missing entries" do
|
22
|
+
provider = TestProvider.new({
|
23
|
+
"foo.css" => "a { color: red; }",
|
24
|
+
:default => "body { color: green; }",
|
25
|
+
})
|
26
|
+
provider.find_stylesheet("foo.css").to_s.should_not include("body")
|
27
|
+
provider.find_stylesheet("bar.css").to_s.should include("body")
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
module Roadie
|
5
|
+
describe UrlGenerator do
|
6
|
+
it "is initialized with URL options" do
|
7
|
+
UrlGenerator.new(host: "foo.com").url_options.should == {host: "foo.com"}
|
8
|
+
end
|
9
|
+
|
10
|
+
it "raises an argument error if no URL options are specified" do
|
11
|
+
expect {
|
12
|
+
UrlGenerator.new(nil)
|
13
|
+
}.to raise_error ArgumentError, /url options/i
|
14
|
+
end
|
15
|
+
|
16
|
+
it "raises an argument error if no host is specified" do
|
17
|
+
expect {
|
18
|
+
UrlGenerator.new(port: 3000)
|
19
|
+
}.to raise_error ArgumentError, /host/i
|
20
|
+
end
|
21
|
+
|
22
|
+
it "raises an argument error if unknown option is passed" do
|
23
|
+
expect {
|
24
|
+
UrlGenerator.new(host: "localhost", secret: true)
|
25
|
+
}.to raise_error ArgumentError, /secret/
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "generating URLs" do
|
29
|
+
def url(path, options = {})
|
30
|
+
UrlGenerator.new(options).generate_url(path)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "uses the given host" do
|
34
|
+
url("/hello.jpg", host: "goats.com").should == "http://goats.com/hello.jpg"
|
35
|
+
end
|
36
|
+
|
37
|
+
it "uses the given port" do
|
38
|
+
url("/", host: "example.com", port: 1337).should == "http://example.com:1337/"
|
39
|
+
end
|
40
|
+
|
41
|
+
it "uses the given scheme" do
|
42
|
+
url("/", host: "example.com", scheme: "https").should == "https://example.com/"
|
43
|
+
end
|
44
|
+
|
45
|
+
it "regards :protocol as an alias for scheme" do
|
46
|
+
url("/", host: "example.com", protocol: "https").should == "https://example.com/"
|
47
|
+
end
|
48
|
+
|
49
|
+
it "strips extra characters from the scheme" do
|
50
|
+
url("/", host: "example.com", scheme: "https://").should == "https://example.com/"
|
51
|
+
end
|
52
|
+
|
53
|
+
it "uses the given path as a prefix" do
|
54
|
+
url("/my_file", host: "example.com", path: "/my_app").should ==
|
55
|
+
"http://example.com/my_app/my_file"
|
56
|
+
end
|
57
|
+
|
58
|
+
it "returns the original URL if it is absolute" do
|
59
|
+
url("http://foo.com/", host: "bar.com").should == "http://foo.com/"
|
60
|
+
end
|
61
|
+
|
62
|
+
it "returns the base URL for blank paths" do
|
63
|
+
url("", host: "foo.com").should == "http://foo.com"
|
64
|
+
url(nil, host: "foo.com").should == "http://foo.com"
|
65
|
+
end
|
66
|
+
|
67
|
+
it "raises an error on invalid path" do
|
68
|
+
expect {
|
69
|
+
url("://", host: "example.com")
|
70
|
+
}.to raise_error InvalidUrlPath, %r{://}
|
71
|
+
end
|
72
|
+
|
73
|
+
it "accepts base paths without a slash in the beginning" do
|
74
|
+
url("/bar", host: "example.com", path: "foo").should == "http://example.com/foo/bar"
|
75
|
+
url("/bar/", host: "example.com", path: "foo/").should == "http://example.com/foo/bar/"
|
76
|
+
end
|
77
|
+
|
78
|
+
it "accepts input paths without a slash in the beginning" do
|
79
|
+
url("bar", host: "example.com", path: "/foo").should == "http://example.com/foo/bar"
|
80
|
+
url("bar", host: "example.com", path: "/foo/").should == "http://example.com/foo/bar"
|
81
|
+
end
|
82
|
+
|
83
|
+
it "does not touch data: URIs" do
|
84
|
+
url("data:deadbeef", host: "example.com").should == "data:deadbeef"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# URLs in resources that are not based inside the root requires that we may
|
89
|
+
# specify a "custom base" to properly handle relative paths. Here's an
|
90
|
+
# example:
|
91
|
+
#
|
92
|
+
# # /
|
93
|
+
# # document.html
|
94
|
+
# # images/
|
95
|
+
# # bg.png
|
96
|
+
# # stylesheets/
|
97
|
+
# # my_style.css
|
98
|
+
#
|
99
|
+
# # stylesheets/my_style.css
|
100
|
+
# body { background-image: url(../images/bg.png); }
|
101
|
+
#
|
102
|
+
# In this example, the stylesheet refers to /images/bg.png by using a
|
103
|
+
# relative path from /stylesheets/. In order to understand these cases, we
|
104
|
+
# need to specify where the "base" is in relation to the root.
|
105
|
+
describe "generating URLs with custom base" do
|
106
|
+
it "resolves relative paths" do
|
107
|
+
generator = UrlGenerator.new(host: "foo.com")
|
108
|
+
generator.generate_url("../images/bg.png", "/stylesheets").should == "http://foo.com/images/bg.png"
|
109
|
+
generator.generate_url("../images/bg.png", "email/stylesheets").should == "http://foo.com/email/images/bg.png"
|
110
|
+
generator.generate_url("images/bg.png", "email/").should == "http://foo.com/email/images/bg.png"
|
111
|
+
end
|
112
|
+
|
113
|
+
it "does not use the base when presented with a root-based path" do
|
114
|
+
generator = UrlGenerator.new(host: "foo.com")
|
115
|
+
generator.generate_url("/images/bg.png", "/stylesheets").should == "http://foo.com/images/bg.png"
|
116
|
+
generator.generate_url("/images/bg.png", "email/stylesheets").should == "http://foo.com/images/bg.png"
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'shared_examples/url_rewriter'
|
3
|
+
|
4
|
+
module Roadie
|
5
|
+
describe UrlRewriter do
|
6
|
+
let(:generator) { double("URL generator") }
|
7
|
+
subject(:rewriter) { UrlRewriter.new(generator) }
|
8
|
+
|
9
|
+
it_behaves_like "url rewriter"
|
10
|
+
|
11
|
+
describe "transforming DOM trees" do
|
12
|
+
def dom_document(html); Nokogiri::HTML.parse html; end
|
13
|
+
|
14
|
+
it "rewrites all a[href]" do
|
15
|
+
generator.should_receive(:generate_url).with("some/path").and_return "http://foo.com/"
|
16
|
+
dom = dom_document <<-HTML
|
17
|
+
<body>
|
18
|
+
<a href="some/path">Some path</a>
|
19
|
+
</body>
|
20
|
+
HTML
|
21
|
+
|
22
|
+
expect {
|
23
|
+
rewriter.transform_dom dom
|
24
|
+
}.to change { dom.at_css("a")["href"] }.to "http://foo.com/"
|
25
|
+
end
|
26
|
+
|
27
|
+
it "rewrites relative img[src]" do
|
28
|
+
generator.should_receive(:generate_url).with("some/path.jpg").and_return "http://foo.com/image.jpg"
|
29
|
+
dom = dom_document <<-HTML
|
30
|
+
<body>
|
31
|
+
<img src="some/path.jpg">
|
32
|
+
</body>
|
33
|
+
HTML
|
34
|
+
|
35
|
+
expect {
|
36
|
+
rewriter.transform_dom dom
|
37
|
+
}.to change { dom.at_css("img")["src"] }.to "http://foo.com/image.jpg"
|
38
|
+
end
|
39
|
+
|
40
|
+
it "rewrites url() directives inside style attributes" do
|
41
|
+
generator.should_receive(:generate_url).with("some/path.jpg").and_return "http://foo.com/image.jpg"
|
42
|
+
dom = dom_document <<-HTML
|
43
|
+
<body>
|
44
|
+
<div style="background-image: url("some/path.jpg");">
|
45
|
+
</body>
|
46
|
+
HTML
|
47
|
+
|
48
|
+
expect {
|
49
|
+
rewriter.transform_dom dom
|
50
|
+
}.to change { dom.at_css("div")["style"] }.to 'background-image: url("http://foo.com/image.jpg");'
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "transforming css" do
|
55
|
+
it "rewrites all url() directives" do
|
56
|
+
generator.should_receive(:generate_url).with("some/path.jpg").and_return "http://foo.com/image.jpg"
|
57
|
+
css = "body { background: top url(some/path.jpg) #eee; }"
|
58
|
+
expect {
|
59
|
+
rewriter.transform_css css
|
60
|
+
}.to change { css }.to "body { background: top url(http://foo.com/image.jpg) #eee; }"
|
61
|
+
end
|
62
|
+
|
63
|
+
it "correctly identifies URLs with single quotes" do
|
64
|
+
generator.should_receive(:generate_url).with("images/foo.png").and_return "x"
|
65
|
+
rewriter.transform_css "url('images/foo.png')"
|
66
|
+
end
|
67
|
+
|
68
|
+
it "correctly identifies URLs with double quotes" do
|
69
|
+
generator.should_receive(:generate_url).with("images/foo.png").and_return "x"
|
70
|
+
rewriter.transform_css 'url("images/foo.png")'
|
71
|
+
end
|
72
|
+
|
73
|
+
it "correctly identifies URLs with parenthesis inside them" do
|
74
|
+
generator.should_receive(:generate_url).with("images/map_(large_(extra)).png").and_return "x"
|
75
|
+
rewriter.transform_css 'url(images/map_(large_(extra)).png)'
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
shared_examples_for "asset provider role" do
|
2
|
+
it "responds to #find_stylesheet" do
|
3
|
+
subject.should respond_to(:find_stylesheet)
|
4
|
+
subject.method(:find_stylesheet).arity.should == 1
|
5
|
+
end
|
6
|
+
|
7
|
+
it "responds to #find_stylesheet!" do
|
8
|
+
subject.should respond_to(:find_stylesheet!)
|
9
|
+
subject.method(:find_stylesheet!).arity.should == 1
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
shared_examples_for "url rewriter" do
|
2
|
+
it "is constructed with a generator" do
|
3
|
+
generator = double "URL generator"
|
4
|
+
expect {
|
5
|
+
described_class.new(generator)
|
6
|
+
}.to_not raise_error
|
7
|
+
end
|
8
|
+
|
9
|
+
it "has a #transform_dom(dom) method that returns nil" do
|
10
|
+
subject.should respond_to(:transform_dom)
|
11
|
+
subject.method(:transform_dom).arity.should == 1
|
12
|
+
|
13
|
+
dom = Nokogiri::HTML.parse "<body></body>"
|
14
|
+
subject.transform_dom(dom).should be_nil
|
15
|
+
end
|
16
|
+
|
17
|
+
it "has a #transform_css(css) method that returns nil" do
|
18
|
+
subject.should respond_to(:transform_css)
|
19
|
+
subject.method(:transform_css).arity.should == 1
|
20
|
+
|
21
|
+
subject.transform_css("").should be_nil
|
22
|
+
end
|
23
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,67 +1,12 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
require 'rubygems'
|
5
|
-
require 'bundler'
|
6
|
-
|
7
|
-
begin
|
8
|
-
Bundler.setup(:default, :development)
|
9
|
-
rescue Bundler::BundlerError => e
|
10
|
-
$stderr.puts e.message
|
11
|
-
$stderr.puts "Run `bundle install` to install missing gems"
|
12
|
-
exit e.status_code
|
13
|
-
end
|
14
|
-
|
15
|
-
require 'rspec'
|
16
|
-
require 'rails'
|
17
|
-
require 'sprockets'
|
18
|
-
|
19
|
-
require 'roadie/railtie'
|
20
|
-
require 'action_mailer/railtie'
|
21
|
-
|
22
|
-
FIXTURES_PATH = Pathname.new(File.dirname(__FILE__)).join('fixtures')
|
23
|
-
|
24
|
-
class TestApplication < Rails::Application
|
25
|
-
def config
|
26
|
-
@config
|
27
|
-
end
|
28
|
-
|
29
|
-
def assets
|
30
|
-
env = Sprockets::Environment.new
|
31
|
-
env.append_path root.join('app','assets','stylesheets')
|
32
|
-
env
|
33
|
-
end
|
34
|
-
|
35
|
-
def root
|
36
|
-
FIXTURES_PATH
|
37
|
-
end
|
38
|
-
|
39
|
-
def reset_test_config
|
40
|
-
@config = OpenStruct.new({
|
41
|
-
:action_mailer => OpenStruct.new(:default_url_options => {}),
|
42
|
-
:assets => OpenStruct.new(:enabled => false),
|
43
|
-
:roadie => OpenStruct.new(:provider => nil, :enabled => true),
|
44
|
-
})
|
45
|
-
change_default_url_options(:host => "example.com")
|
46
|
-
end
|
1
|
+
if ENV['CI']
|
2
|
+
require 'coveralls'
|
3
|
+
Coveralls.wear!
|
47
4
|
end
|
48
5
|
|
49
|
-
|
50
|
-
|
51
|
-
ActionMailer::Railtie.run_initializers(:default, Rails.application)
|
52
|
-
Roadie::Railtie.run_initializers(:default, Rails.application)
|
53
|
-
else
|
54
|
-
# Rails 3.0
|
55
|
-
Rails.application.config.active_support.deprecation = :log
|
56
|
-
Rails.logger = Logger.new('/dev/null')
|
57
|
-
Rails.application.initialize!
|
58
|
-
end
|
6
|
+
$: << File.dirname(__FILE__) + '/../lib'
|
7
|
+
require 'roadie'
|
59
8
|
|
60
9
|
RSpec.configure do |config|
|
61
|
-
config.before(:each) do
|
62
|
-
Rails.application.reset_test_config
|
63
|
-
end
|
64
|
-
|
65
10
|
config.treat_symbols_as_metadata_keys_with_true_values = true
|
66
11
|
config.run_all_when_everything_filtered = true
|
67
12
|
end
|
@@ -3,9 +3,9 @@ RSpec::Matchers.define :have_node do |selector|
|
|
3
3
|
match do |document|
|
4
4
|
node = document.at_css(selector)
|
5
5
|
if @attributes
|
6
|
-
node
|
6
|
+
node && match_attributes(node.attributes)
|
7
7
|
else
|
8
|
-
node
|
8
|
+
node
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
@@ -1,5 +1,5 @@
|
|
1
1
|
RSpec::Matchers.define :have_selector do |selector|
|
2
|
-
match { |document| document.css(selector).
|
2
|
+
match { |document| !document.css(selector).empty? }
|
3
3
|
failure_message_for_should { "expected document to #{name_to_sentence}#{expected_to_sentence}"}
|
4
4
|
failure_message_for_should_not { "expected document to not #{name_to_sentence}#{expected_to_sentence}"}
|
5
5
|
end
|
@@ -1,25 +1,59 @@
|
|
1
1
|
RSpec::Matchers.define :have_styling do |rules|
|
2
2
|
@selector = 'body > *:first'
|
3
|
+
normalized_rules = StylingExpectation.new(rules)
|
3
4
|
|
4
|
-
chain
|
5
|
-
|
5
|
+
chain(:at_selector) { |selector| @selector = selector }
|
6
|
+
match { |document| normalized_rules == styles_at_selector(document) }
|
7
|
+
|
8
|
+
description {
|
9
|
+
"have styles #{normalized_rules.inspect} at selector #{@selector.inspect}"
|
10
|
+
}
|
11
|
+
|
12
|
+
failure_message_for_should { |document|
|
13
|
+
"expected styles at #{@selector.inspect} to be:\n#{normalized_rules}\nbut was:\n#{styles_at_selector(document)}"
|
14
|
+
}
|
15
|
+
|
16
|
+
failure_message_for_should_not {
|
17
|
+
"expected styles at #{@selector.inspect} to not be:\n#{normalized_rules}"
|
18
|
+
}
|
19
|
+
|
20
|
+
def styles_at_selector(document)
|
21
|
+
document.should have_selector(@selector)
|
22
|
+
StylingExpectation.new document.at_css(@selector)['style']
|
6
23
|
end
|
24
|
+
end
|
7
25
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
26
|
+
class StylingExpectation
|
27
|
+
def initialize(styling)
|
28
|
+
case styling
|
29
|
+
when String then @rules = parse_rules(styling)
|
30
|
+
when Array then @rules = styling
|
31
|
+
when Hash then @rules = styling.to_a
|
32
|
+
else fail "I don't understand #{styling.inspect}!"
|
13
33
|
end
|
14
34
|
end
|
15
35
|
|
16
|
-
|
17
|
-
|
18
|
-
|
36
|
+
def ==(other)
|
37
|
+
rules == other.rules
|
38
|
+
end
|
39
|
+
|
40
|
+
def to_s() rules.to_s end
|
19
41
|
|
20
|
-
|
21
|
-
|
22
|
-
|
42
|
+
protected
|
43
|
+
attr_reader :rules
|
44
|
+
|
45
|
+
private
|
46
|
+
def parse_rules(css)
|
47
|
+
css.split(';').map { |property| parse_property(property) }
|
48
|
+
end
|
49
|
+
|
50
|
+
def parse_property(property)
|
51
|
+
rule, value = property.split(':', 2).map(&:strip)
|
52
|
+
[rule, normalize_quotes(value)]
|
23
53
|
end
|
24
|
-
end
|
25
54
|
|
55
|
+
# JRuby's Nokogiri encodes quotes
|
56
|
+
def normalize_quotes(string)
|
57
|
+
string.gsub '%22', '"'
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class TestProvider
|
2
|
+
include Roadie::AssetProvider
|
3
|
+
|
4
|
+
def initialize(files = {})
|
5
|
+
@files = files
|
6
|
+
@default = files[:default]
|
7
|
+
end
|
8
|
+
|
9
|
+
def find_stylesheet(name)
|
10
|
+
contents = @files.fetch(name, @default)
|
11
|
+
Roadie::Stylesheet.new name, contents if contents
|
12
|
+
end
|
13
|
+
end
|