roadie 2.4.3 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +3 -0
- data/.travis.yml +10 -14
- data/.yardopts +1 -1
- data/Changelog.md +38 -5
- data/Gemfile +3 -4
- data/Guardfile +12 -1
- data/README.md +168 -164
- data/Rakefile +2 -19
- data/lib/roadie.rb +15 -68
- 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 +30 -60
- data/lib/roadie/inliner.rb +72 -217
- 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 +71 -0
- data/lib/roadie/rspec.rb +1 -0
- data/lib/roadie/rspec/asset_provider.rb +49 -0
- data/lib/roadie/selector.rb +43 -18
- data/lib/roadie/style_attribute_builder.rb +25 -0
- data/lib/roadie/style_block.rb +32 -0
- data/lib/roadie/style_property.rb +93 -0
- data/lib/roadie/stylesheet.rb +65 -0
- data/lib/roadie/upgrade_guide.rb +36 -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 +8 -11
- 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 +17 -0
- data/spec/lib/roadie/document_spec.rb +123 -0
- data/spec/lib/roadie/filesystem_provider_spec.rb +44 -68
- 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 +89 -0
- data/spec/lib/roadie/selector_spec.rb +15 -10
- data/spec/lib/roadie/style_attribute_builder_spec.rb +29 -0
- data/spec/lib/roadie/style_block_spec.rb +35 -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 +121 -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 +6 -60
- data/spec/support/have_attribute_matcher.rb +2 -2
- data/spec/support/have_node_matcher.rb +4 -4
- data/spec/support/have_selector_matcher.rb +3 -3
- data/spec/support/have_styling_matcher.rb +51 -15
- data/spec/support/test_provider.rb +13 -0
- metadata +86 -175
- 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,78 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
module Roadie
|
5
|
+
describe MarkupImprover do
|
6
|
+
def improve(html)
|
7
|
+
dom = Nokogiri::HTML.parse html
|
8
|
+
MarkupImprover.new(dom, html).improve
|
9
|
+
dom
|
10
|
+
end
|
11
|
+
|
12
|
+
# JRuby up to at least 1.6.0 has a bug where the doctype of a document cannot be changed.
|
13
|
+
# See https://github.com/sparklemotion/nokogiri/issues/984
|
14
|
+
def pending_for_buggy_jruby
|
15
|
+
# No reason to check for version yet since no existing version has a fix.
|
16
|
+
skip "Pending until Nokogiri issue #984 is fixed and released" if defined?(JRuby)
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "automatic doctype" do
|
20
|
+
it "inserts a HTML5 doctype if no doctype is present" do
|
21
|
+
pending_for_buggy_jruby
|
22
|
+
expect(improve("<html></html>").internal_subset.to_xml).to eq("<!DOCTYPE html>")
|
23
|
+
end
|
24
|
+
|
25
|
+
it "does not insert duplicate doctypes" do
|
26
|
+
html = improve('<!DOCTYPE html><html><body></body></html>').to_html
|
27
|
+
expect(html.scan('DOCTYPE').size).to eq(1)
|
28
|
+
end
|
29
|
+
|
30
|
+
it "leaves other doctypes alone" do
|
31
|
+
dtd = "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"http://www.w3.org/TR/REC-html40/loose.dtd\">"
|
32
|
+
html = "#{dtd}<html></html>"
|
33
|
+
expect(improve(html).internal_subset.to_xml.strip).to eq(dtd)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "basic HTML structure" do
|
38
|
+
it "inserts a <html> element as the root" do
|
39
|
+
expect(improve("<h1>Hey!</h1>")).to have_selector("html h1")
|
40
|
+
expect(improve("<html></html>").css('html').size).to eq(1)
|
41
|
+
end
|
42
|
+
|
43
|
+
it "inserts <head> if not present" do
|
44
|
+
expect(improve('<html><body></body></html>')).to have_selector('html > head + body')
|
45
|
+
expect(improve('<html></html>')).to have_selector('html > head')
|
46
|
+
expect(improve('Foo')).to have_selector('html > head')
|
47
|
+
expect(improve('<html><head></head></html>').css('head').size).to eq(1)
|
48
|
+
end
|
49
|
+
|
50
|
+
it "inserts <body> if not present" do
|
51
|
+
expect(improve('<h1>Hey!</h1>')).to have_selector('html > body > h1')
|
52
|
+
expect(improve('<html><h1>Hey!</h1></html>')).to have_selector('html > body > h1')
|
53
|
+
expect(improve('<html><body><h1>Hey!</h1></body></html>').css('body').size).to eq(1)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe "charset declaration" do
|
58
|
+
it "is inserted if missing" do
|
59
|
+
dom = improve('<html><head></head><body></body></html>')
|
60
|
+
|
61
|
+
expect(dom).to have_selector('head meta')
|
62
|
+
meta = dom.at_css('head meta')
|
63
|
+
expect(meta['http-equiv']).to eq('Content-Type')
|
64
|
+
expect(meta['content']).to eq('text/html; charset=UTF-8')
|
65
|
+
end
|
66
|
+
|
67
|
+
it "is left alone when predefined" do
|
68
|
+
expect(improve(<<-HTML).xpath('//meta')).to have(1).item
|
69
|
+
<html>
|
70
|
+
<head>
|
71
|
+
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
|
72
|
+
</head>
|
73
|
+
</html>
|
74
|
+
HTML
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require 'spec_helper'
|
3
|
+
require 'shared_examples/asset_provider'
|
4
|
+
|
5
|
+
module Roadie
|
6
|
+
describe NullProvider do
|
7
|
+
it_behaves_like "asset provider role"
|
8
|
+
|
9
|
+
def expect_empty_stylesheet(stylesheet)
|
10
|
+
expect(stylesheet).not_to be_nil
|
11
|
+
expect(stylesheet.name).to eq("(null)")
|
12
|
+
expect(stylesheet).to have(0).blocks
|
13
|
+
expect(stylesheet.to_s).to be_empty
|
14
|
+
end
|
15
|
+
|
16
|
+
it "finds an empty stylesheet for every name" do
|
17
|
+
expect_empty_stylesheet NullProvider.new.find_stylesheet("omg wtf bbq")
|
18
|
+
expect_empty_stylesheet NullProvider.new.find_stylesheet!("omg wtf bbq")
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require 'spec_helper'
|
3
|
+
require 'shared_examples/url_rewriter'
|
4
|
+
|
5
|
+
module Roadie
|
6
|
+
describe NullUrlRewriter do
|
7
|
+
let(:generator) { double "URL generator" }
|
8
|
+
subject(:rewriter) { NullUrlRewriter.new(generator) }
|
9
|
+
|
10
|
+
it_behaves_like "url rewriter"
|
11
|
+
|
12
|
+
it "does nothing when transforming DOM" do
|
13
|
+
dom = double "DOM tree"
|
14
|
+
expect {
|
15
|
+
NullUrlRewriter.new(generator).transform_dom dom
|
16
|
+
}.to_not raise_error
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require 'spec_helper'
|
3
|
+
require 'roadie/rspec'
|
4
|
+
|
5
|
+
module Roadie
|
6
|
+
describe ProviderList do
|
7
|
+
let(:test_provider) { TestProvider.new }
|
8
|
+
subject(:provider) { ProviderList.new([test_provider]) }
|
9
|
+
|
10
|
+
it_behaves_like "roadie asset provider", valid_name: "valid", invalid_name: "invalid" do
|
11
|
+
let(:test_provider) { TestProvider.new "valid" => "" }
|
12
|
+
end
|
13
|
+
|
14
|
+
it "finds using all given providers" do
|
15
|
+
first = TestProvider.new "foo.css" => "foo { color: green; }"
|
16
|
+
second = TestProvider.new "bar.css" => "bar { color: green; }"
|
17
|
+
provider = ProviderList.new [first, second]
|
18
|
+
|
19
|
+
expect(provider.find_stylesheet("foo.css").to_s).to include "foo"
|
20
|
+
expect(provider.find_stylesheet("bar.css").to_s).to include "bar"
|
21
|
+
expect(provider.find_stylesheet("baz.css")).to be_nil
|
22
|
+
end
|
23
|
+
|
24
|
+
it "is enumerable" do
|
25
|
+
expect(provider).to be_kind_of(Enumerable)
|
26
|
+
expect(provider).to respond_to(:each)
|
27
|
+
expect(provider.each.to_a).to eq([test_provider])
|
28
|
+
end
|
29
|
+
|
30
|
+
it "has a size" do
|
31
|
+
expect(provider.size).to eq(1)
|
32
|
+
expect(provider).not_to be_empty
|
33
|
+
end
|
34
|
+
|
35
|
+
it "has a first and a last element" do
|
36
|
+
providers = [double("1"), double("2"), double("3")]
|
37
|
+
list = ProviderList.new(providers)
|
38
|
+
expect(list.first).to eq(providers.first)
|
39
|
+
expect(list.last).to eq(providers.last)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "can have providers pushed and popped" do
|
43
|
+
other = double "Some other provider"
|
44
|
+
|
45
|
+
expect {
|
46
|
+
provider.push other
|
47
|
+
provider << other
|
48
|
+
}.to change(provider, :size).by(2)
|
49
|
+
|
50
|
+
expect {
|
51
|
+
expect(provider.pop).to eq(other)
|
52
|
+
}.to change(provider, :size).by(-1)
|
53
|
+
end
|
54
|
+
|
55
|
+
it "can have providers shifted and unshifted" do
|
56
|
+
other = double "Some other provider"
|
57
|
+
|
58
|
+
expect {
|
59
|
+
provider.unshift other
|
60
|
+
}.to change(provider, :size).by(1)
|
61
|
+
|
62
|
+
expect {
|
63
|
+
expect(provider.shift).to eq(other)
|
64
|
+
}.to change(provider, :size).by(-1)
|
65
|
+
end
|
66
|
+
|
67
|
+
describe "wrapping" do
|
68
|
+
it "creates provider lists with the arguments" do
|
69
|
+
expect(ProviderList.wrap(test_provider)).to be_instance_of(ProviderList)
|
70
|
+
expect(ProviderList.wrap(test_provider, test_provider).size).to eq(2)
|
71
|
+
end
|
72
|
+
|
73
|
+
it "flattens arrays" do
|
74
|
+
expect(ProviderList.wrap([test_provider, test_provider], test_provider).size).to eq(3)
|
75
|
+
expect(ProviderList.wrap([test_provider, test_provider]).size).to eq(2)
|
76
|
+
end
|
77
|
+
|
78
|
+
it "combines with providers from other lists" do
|
79
|
+
other_list = ProviderList.new([test_provider, test_provider])
|
80
|
+
expect(ProviderList.wrap(test_provider, other_list).size).to eq(3)
|
81
|
+
end
|
82
|
+
|
83
|
+
it "returns the passed list if only a single ProviderList is passed" do
|
84
|
+
other_list = ProviderList.new([test_provider])
|
85
|
+
expect(ProviderList.wrap(other_list)).to eql other_list
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -4,11 +4,11 @@ require 'spec_helper'
|
|
4
4
|
module Roadie
|
5
5
|
describe Selector do
|
6
6
|
it "can be coerced into String" do
|
7
|
-
("I love " + Selector.new("html")).
|
7
|
+
expect("I love " + Selector.new("html")).to eq("I love html")
|
8
8
|
end
|
9
9
|
|
10
10
|
it "can be inlined when simple" do
|
11
|
-
Selector.new("html body #main p.class").
|
11
|
+
expect(Selector.new("html body #main p.class")).to be_inlinable
|
12
12
|
end
|
13
13
|
|
14
14
|
it "cannot be inlined when containing pseudo functions" do
|
@@ -27,32 +27,37 @@ module Roadie
|
|
27
27
|
p:disabled
|
28
28
|
p:checked
|
29
29
|
].each do |bad_selector|
|
30
|
-
Selector.new(bad_selector).
|
30
|
+
expect(Selector.new(bad_selector)).not_to be_inlinable
|
31
31
|
end
|
32
32
|
|
33
|
-
Selector.new('p.active').
|
33
|
+
expect(Selector.new('p.active')).to be_inlinable
|
34
34
|
end
|
35
35
|
|
36
36
|
it "cannot be inlined when containing pseudo elements" do
|
37
|
-
Selector.new('p::some-element').
|
37
|
+
expect(Selector.new('p::some-element')).not_to be_inlinable
|
38
38
|
end
|
39
39
|
|
40
40
|
it "cannot be inlined when selector is an at-rule" do
|
41
|
-
Selector.new('@keyframes progress-bar-stripes').
|
41
|
+
expect(Selector.new('@keyframes progress-bar-stripes')).not_to be_inlinable
|
42
42
|
end
|
43
43
|
|
44
44
|
it "has a calculated specificity" do
|
45
45
|
selector = "html p.active.nice #main.deep-selector"
|
46
|
-
Selector.new(selector).specificity.
|
46
|
+
expect(Selector.new(selector).specificity).to eq(CssParser.calculate_specificity(selector))
|
47
|
+
end
|
48
|
+
|
49
|
+
it "can be told about the specificity at initialization" do
|
50
|
+
selector = "html p.active.nice #main.deep-selector"
|
51
|
+
expect(Selector.new(selector, 1337).specificity).to eq(1337)
|
47
52
|
end
|
48
53
|
|
49
54
|
it "is equal to other selectors when they match the same things" do
|
50
|
-
Selector.new("foo").
|
51
|
-
Selector.new("foo").
|
55
|
+
expect(Selector.new("foo")).to eq(Selector.new("foo "))
|
56
|
+
expect(Selector.new("foo")).not_to eq("foo")
|
52
57
|
end
|
53
58
|
|
54
59
|
it "strips the given selector" do
|
55
|
-
Selector.new(" foo \n").to_s.
|
60
|
+
expect(Selector.new(" foo \n").to_s).to eq(Selector.new("foo").to_s)
|
56
61
|
end
|
57
62
|
end
|
58
63
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Roadie
|
4
|
+
describe StyleAttributeBuilder do
|
5
|
+
it "sorts the added properties" do
|
6
|
+
builder = StyleAttributeBuilder.new
|
7
|
+
|
8
|
+
builder << StyleProperty.new("color", "green", true, 1)
|
9
|
+
builder << StyleProperty.new("font-size", "110%", false, 15)
|
10
|
+
builder << StyleProperty.new("color", "red", false, 15)
|
11
|
+
|
12
|
+
expect(builder.attribute_string).to eq "font-size:110%;color:red;color:green !important"
|
13
|
+
end
|
14
|
+
|
15
|
+
it "preserves the order of added attributes with the same specificity" do
|
16
|
+
builder = StyleAttributeBuilder.new
|
17
|
+
|
18
|
+
builder << StyleProperty.new("color", "pink", false, 50)
|
19
|
+
builder << StyleProperty.new("color", "red", false, 50)
|
20
|
+
builder << StyleProperty.new("color", "green", false, 50)
|
21
|
+
|
22
|
+
# We need one different element to trigger the problem with Ruby's
|
23
|
+
# unstable sort
|
24
|
+
builder << StyleProperty.new("background", "white", false, 1)
|
25
|
+
|
26
|
+
expect(builder.attribute_string).to eq "background:white;color:pink;color:red;color:green"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
module Roadie
|
5
|
+
describe StyleBlock do
|
6
|
+
it "has a selector and a list of properties" do
|
7
|
+
properties = []
|
8
|
+
selector = double "Selector"
|
9
|
+
|
10
|
+
block = StyleBlock.new(selector, properties)
|
11
|
+
expect(block.selector).to eq(selector)
|
12
|
+
expect(block.properties).to eq(properties)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "delegates #specificity to the selector" do
|
16
|
+
selector = double "Selector", specificity: 45
|
17
|
+
expect(StyleBlock.new(selector, []).specificity).to eq(45)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "delegates #inlinable? to the selector" do
|
21
|
+
selector = double "Selector", inlinable?: "maybe"
|
22
|
+
expect(StyleBlock.new(selector, []).inlinable?).to eq("maybe")
|
23
|
+
end
|
24
|
+
|
25
|
+
it "delegates #selector_string to selector#to_s" do
|
26
|
+
selector = double "Selector", to_s: "yey"
|
27
|
+
expect(StyleBlock.new(selector, []).selector_string).to eq("yey")
|
28
|
+
end
|
29
|
+
|
30
|
+
it "has a string representation" do
|
31
|
+
properties = [double(to_s: "bar"), double(to_s: "baz")]
|
32
|
+
expect(StyleBlock.new(double(to_s: "foo"), properties).to_s).to eq("foo{bar;baz}")
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Roadie
|
4
|
+
describe StyleProperty do
|
5
|
+
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')
|
9
|
+
expect(declaration).to be_important
|
10
|
+
expect(declaration.specificity).to eq(45)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "string representation" do
|
15
|
+
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
|
+
end
|
19
|
+
|
20
|
+
it "contains the !important flag when set" do
|
21
|
+
expect(StyleProperty.new('color', 'green', true, 1).to_s).to eq('color:green !important')
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "comparing" do
|
26
|
+
def declaration(specificity, important = false)
|
27
|
+
StyleProperty.new('color', 'green', important, specificity)
|
28
|
+
end
|
29
|
+
|
30
|
+
it "compares on specificity" do
|
31
|
+
expect(declaration(5)).to eq(declaration(5))
|
32
|
+
expect(declaration(4)).to be < declaration(5)
|
33
|
+
expect(declaration(6)).to be > declaration(5)
|
34
|
+
end
|
35
|
+
|
36
|
+
context "with an important declaration" do
|
37
|
+
it "is less than the important declaration regardless of the specificity" do
|
38
|
+
expect(declaration(99, false)).to be < declaration(1, true)
|
39
|
+
end
|
40
|
+
|
41
|
+
it "compares like normal when both declarations are important" do
|
42
|
+
expect(declaration(5, true)).to eq(declaration(5, true))
|
43
|
+
expect(declaration(4, true)).to be < declaration(5, true)
|
44
|
+
expect(declaration(6, true)).to be > declaration(5, true)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe "parsing" do
|
50
|
+
def parsing(declaration, specificity)
|
51
|
+
property = StyleProperty.parse(declaration, specificity)
|
52
|
+
[property.property, property.value, property.important?, property.specificity]
|
53
|
+
end
|
54
|
+
|
55
|
+
it "understands simple declarations" do
|
56
|
+
expect(parsing("color: green", 1)).to eq(["color", "green", false, 1])
|
57
|
+
expect(parsing(" color:green; ", 1)).to eq(["color", "green", false, 1])
|
58
|
+
expect(parsing("color: green ", 1)).to eq(["color", "green", false, 1])
|
59
|
+
expect(parsing("color: green ; ", 1)).to eq(["color", "green", false, 1])
|
60
|
+
end
|
61
|
+
|
62
|
+
it "understands more complex values" do
|
63
|
+
expect(parsing("padding:0 1px 5rem 9%;", 89)).to eq(["padding", "0 1px 5rem 9%", false, 89])
|
64
|
+
end
|
65
|
+
|
66
|
+
it "understands more complex names" do
|
67
|
+
expect(parsing("font-size: 50%", 10)).to eq(["font-size", "50%", false, 10])
|
68
|
+
end
|
69
|
+
|
70
|
+
it "correctly reads !important declarations" do
|
71
|
+
expect(parsing("color: green !important", 1)).to eq(["color", "green", true, 1])
|
72
|
+
expect(parsing("color: green !important;", 1)).to eq(["color", "green", true, 1])
|
73
|
+
end
|
74
|
+
|
75
|
+
it "raises an error on unparseable declarations" do
|
76
|
+
expect {
|
77
|
+
parsing("I want a red apple!", 1)
|
78
|
+
}.to raise_error(Roadie::UnparseableDeclaration, /red apple/)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
module Roadie
|
5
|
+
describe Stylesheet do
|
6
|
+
it "is initialized with a name and CSS" do
|
7
|
+
stylesheet = Stylesheet.new("foo.css", "body { color: green; }")
|
8
|
+
expect(stylesheet.name).to eq("foo.css")
|
9
|
+
end
|
10
|
+
|
11
|
+
it "has a list of blocks" do
|
12
|
+
stylesheet = Stylesheet.new("foo.css", <<-CSS)
|
13
|
+
body { color: green !important; font-size: 200%; }
|
14
|
+
a, i { color: red; }
|
15
|
+
CSS
|
16
|
+
expect(stylesheet).to have(3).blocks
|
17
|
+
expect(stylesheet.blocks.map(&:to_s)).to eq([
|
18
|
+
"body{color:green !important;font-size:200%}",
|
19
|
+
"a{color:red}",
|
20
|
+
"i{color:red}",
|
21
|
+
])
|
22
|
+
end
|
23
|
+
|
24
|
+
it "can iterate all inlinable blocks" do
|
25
|
+
inlinable = double(inlinable?: true, selector: "good", properties: "props")
|
26
|
+
bad = double(inlinable?: false, selector: "bad", properties: "props")
|
27
|
+
|
28
|
+
stylesheet = Stylesheet.new("example.css", "")
|
29
|
+
allow(stylesheet).to receive_messages blocks: [bad, inlinable, bad]
|
30
|
+
|
31
|
+
expect(stylesheet.each_inlinable_block.to_a).to eq([
|
32
|
+
["good", "props"],
|
33
|
+
])
|
34
|
+
end
|
35
|
+
|
36
|
+
it "has a string representation of the contents" do
|
37
|
+
stylesheet = Stylesheet.new("example.css", "body { color: green;}a{ color: red; font-size: small }")
|
38
|
+
expect(stylesheet.to_s).to eq("body{color:green}\na{color:red;font-size:small}")
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|