dynamic_assets 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +6 -6
- data/app/helpers/dynamic_assets_helpers.rb +17 -13
- data/lib/dynamic_assets/cssmin.rb +110 -0
- data/lib/dynamic_assets/reference/stylesheet_reference.rb +1 -10
- data/lib/dynamic_assets.rb +1 -0
- data/spec/helpers/dynamic_assets_helpers_spec.rb +136 -41
- data/spec/lib/dynamic_assets/stylesheet_reference_spec.rb +88 -7
- data/spec/spec_helper.rb +1 -4
- metadata +4 -3
data/README.rdoc
CHANGED
@@ -41,14 +41,14 @@ dynamically is useful enough that multiple people have thought of implementing i
|
|
41
41
|
<tt>app/assets/javascripts</tt>. Each filename's extension triggers an
|
42
42
|
optional pre-processor:
|
43
43
|
|
44
|
-
.css = raw
|
45
|
-
.js = raw
|
44
|
+
.css = raw CSS
|
45
|
+
.js = raw JS
|
46
46
|
.css.erb = process with ERB
|
47
47
|
.js.erb = process with ERB
|
48
|
-
.
|
49
|
-
.
|
50
|
-
.
|
51
|
-
.
|
48
|
+
.sass = process with Sass and assume sass syntax
|
49
|
+
.scss = process with Sass and assume scss syntax
|
50
|
+
.sass.erb = process with ERB then Sass (sass syntax)
|
51
|
+
.scss.erb = process with ERB then Sass (scss syntax)
|
52
52
|
|
53
53
|
(Note that each file can be processed differently. You could stick one toe
|
54
54
|
into the Sass world by renaming one of your .css files to .scss.)
|
@@ -3,14 +3,12 @@ module DynamicAssetsHelpers
|
|
3
3
|
|
4
4
|
def stylesheet_asset_tag(group_key, http_attributes = {})
|
5
5
|
DynamicAssets::Manager.asset_references_for_group_key(:stylesheets, group_key).map do |asset_ref|
|
6
|
-
path = stylesheet_asset_path asset_ref.name
|
7
|
-
path << "?#{asset_ref.mtime.to_i.to_s}" if asset_ref.mtime.present?
|
8
6
|
|
9
7
|
tag :link, {
|
10
8
|
:type => "text/css",
|
11
9
|
:rel => "stylesheet",
|
12
10
|
:media => "screen",
|
13
|
-
:href =>
|
11
|
+
:href => asset_url(asset_ref)
|
14
12
|
}.merge!(http_attributes)
|
15
13
|
|
16
14
|
end.join.html_safe
|
@@ -18,12 +16,10 @@ module DynamicAssetsHelpers
|
|
18
16
|
|
19
17
|
def javascript_asset_tag(group_key, http_attributes = {})
|
20
18
|
DynamicAssets::Manager.asset_references_for_group_key(:javascripts, group_key).map do |asset_ref|
|
21
|
-
path = javascript_asset_path asset_ref.name
|
22
|
-
path << "?#{asset_ref.mtime.to_i.to_s}" if asset_ref.mtime.present?
|
23
19
|
|
24
20
|
content_tag :script, "", {
|
25
21
|
:type => "text/javascript",
|
26
|
-
:src =>
|
22
|
+
:src => asset_url(asset_ref)
|
27
23
|
}.merge!(http_attributes)
|
28
24
|
|
29
25
|
end.join.html_safe
|
@@ -32,16 +28,24 @@ module DynamicAssetsHelpers
|
|
32
28
|
|
33
29
|
protected
|
34
30
|
|
35
|
-
def
|
36
|
-
|
31
|
+
def asset_path(asset_ref)
|
32
|
+
name = asset_ref.name
|
33
|
+
|
34
|
+
case asset_ref
|
35
|
+
when DynamicAssets::StylesheetReference then stylesheet_asset_path name
|
36
|
+
when DynamicAssets::JavascriptReference then javascript_asset_path name
|
37
|
+
else raise "Unknown asset type: #{asset_ref}"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def asset_url(asset_ref)
|
42
|
+
path = asset_path asset_ref
|
37
43
|
path = "/" + path unless path[0,1] == "/"
|
44
|
+
path << "?#{asset_ref.mtime.to_i.to_s}" if asset_ref.mtime.present?
|
45
|
+
|
38
46
|
host = compute_asset_host path
|
39
47
|
|
40
|
-
|
41
|
-
"#{host}#{path}"
|
42
|
-
else
|
43
|
-
path
|
44
|
-
end
|
48
|
+
host ? "#{host}#{path}" : path
|
45
49
|
end
|
46
50
|
|
47
51
|
# Extracted from Rails' AssetTagHelper, where it's private
|
@@ -0,0 +1,110 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2008 Ryan Grove <ryan@wonko.com>
|
3
|
+
# All rights reserved.
|
4
|
+
#
|
5
|
+
# Redistribution and use in source and binary forms, with or without
|
6
|
+
# modification, are permitted provided that the following conditions are met:
|
7
|
+
#
|
8
|
+
# * Redistributions of source code must retain the above copyright notice,
|
9
|
+
# this list of conditions and the following disclaimer.
|
10
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
11
|
+
# this list of conditions and the following disclaimer in the documentation
|
12
|
+
# and/or other materials provided with the distribution.
|
13
|
+
# * Neither the name of this project nor the names of its contributors may be
|
14
|
+
# used to endorse or promote products derived from this software without
|
15
|
+
# specific prior written permission.
|
16
|
+
#
|
17
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
18
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
19
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
20
|
+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
21
|
+
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
22
|
+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
23
|
+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
24
|
+
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
25
|
+
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
26
|
+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27
|
+
#++
|
28
|
+
|
29
|
+
# = CSSMin
|
30
|
+
#
|
31
|
+
# Minifies CSS using a fast, safe routine adapted from Julien Lecomte's YUI
|
32
|
+
# Compressor, which was in turn adapted from Isaac Schlueter's cssmin PHP
|
33
|
+
# script.
|
34
|
+
#
|
35
|
+
# Author:: Ryan Grove (mailto:ryan@wonko.com)
|
36
|
+
# Version:: 1.0.2 (2008-08-23)
|
37
|
+
# Copyright:: Copyright (c) 2008 Ryan Grove. All rights reserved.
|
38
|
+
# License:: New BSD License (http://opensource.org/licenses/bsd-license.php)
|
39
|
+
# Website:: http://github.com/rgrove/cssmin/
|
40
|
+
#
|
41
|
+
# == Example
|
42
|
+
#
|
43
|
+
# require 'rubygems'
|
44
|
+
# require 'cssmin'
|
45
|
+
#
|
46
|
+
# File.open('example.css', 'r') {|file| puts CSSMin.minify(file) }
|
47
|
+
#
|
48
|
+
module CSSMin
|
49
|
+
|
50
|
+
# Reads CSS from +input+ (which can be a String or an IO object) and
|
51
|
+
# returns a String containing minified CSS.
|
52
|
+
def self.minify(input)
|
53
|
+
css = input.is_a?(IO) ? input.read : input.dup.to_s
|
54
|
+
|
55
|
+
# Remove comments.
|
56
|
+
css.gsub!(/\/\*[\s\S]*?\*\//, '')
|
57
|
+
|
58
|
+
# Compress all runs of whitespace to a single space to make things easier
|
59
|
+
# to work with.
|
60
|
+
css.gsub!(/\s+/, ' ')
|
61
|
+
|
62
|
+
# Replace box model hacks with placeholders.
|
63
|
+
css.gsub!(/"\\"\}\\""/, '___BMH___')
|
64
|
+
|
65
|
+
# Remove unnecessary spaces, but be careful not to turn "p :link {...}"
|
66
|
+
# into "p:link{...}".
|
67
|
+
css.gsub!(/(?:^|\})[^\{:]+\s+:+[^\{]*\{/) do |match|
|
68
|
+
match.gsub(':', '___PSEUDOCLASSCOLON___')
|
69
|
+
end
|
70
|
+
css.gsub!(/\s+([!\{\};:>+\(\)\],])/, '\1')
|
71
|
+
css.gsub!('___PSEUDOCLASSCOLON___', ':')
|
72
|
+
css.gsub!(/([!\{\}:;>+\(\[,])\s+/, '\1')
|
73
|
+
|
74
|
+
# Add missing semicolons.
|
75
|
+
css.gsub!(/([^;\}])\}/, '\1;}')
|
76
|
+
|
77
|
+
# Replace 0(%, em, ex, px, in, cm, mm, pt, pc) with just 0.
|
78
|
+
css.gsub!(/([\s:])([+-]?0)(?:%|em|ex|px|in|cm|mm|pt|pc)/i, '\1\2')
|
79
|
+
|
80
|
+
# Replace 0 0 0 0; with 0.
|
81
|
+
css.gsub!(/:(?:0 )+0;/, ':0;')
|
82
|
+
|
83
|
+
# Replace background-position:0; with background-position:0 0;
|
84
|
+
css.gsub!('background-position:0;', 'background-position:0 0;')
|
85
|
+
|
86
|
+
# Replace 0.6 with .6, but only when preceded by : or a space.
|
87
|
+
css.gsub!(/(:|\s)0+\.(\d+)/, '\1.\2')
|
88
|
+
|
89
|
+
# Convert rgb color values to hex values.
|
90
|
+
css.gsub!(/rgb\s*\(\s*([0-9,\s]+)\s*\)/) do |match|
|
91
|
+
'#' << $1.scan(/\d+/).map{|n| n.to_i.to_s(16).rjust(2, '0') }.join
|
92
|
+
end
|
93
|
+
|
94
|
+
# Compress color hex values, making sure not to touch values used in IE
|
95
|
+
# filters, since they would break.
|
96
|
+
css.gsub!(/([^"'=\s])(\s?)\s*#([0-9a-f])\3([0-9a-f])\4([0-9a-f])\5/i, '\1\2#\3\4\5')
|
97
|
+
|
98
|
+
# Remove empty rules.
|
99
|
+
css.gsub!(/[^\}]+\{;\}\n/, '')
|
100
|
+
|
101
|
+
# Re-insert box model hacks.
|
102
|
+
css.gsub!('___BMH___', '"\"}\""')
|
103
|
+
|
104
|
+
# Prevent redundant semicolons.
|
105
|
+
css.gsub!(/;;+/, ';')
|
106
|
+
|
107
|
+
css.strip
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
@@ -14,6 +14,7 @@ module DynamicAssets
|
|
14
14
|
|
15
15
|
RELATIVE_URL_ROOT = "/stylesheets"
|
16
16
|
|
17
|
+
delegate :minify, :to => CSSMin
|
17
18
|
|
18
19
|
def formats
|
19
20
|
%w(sass scss css)
|
@@ -23,16 +24,6 @@ module DynamicAssets
|
|
23
24
|
:stylesheets
|
24
25
|
end
|
25
26
|
|
26
|
-
def minify(content_string)
|
27
|
-
# From asset_packager. PENDING: replace with github.com/rgrove/cssmin ?
|
28
|
-
content_string.gsub(/\s+/, " ").# collapse space
|
29
|
-
gsub(/\/\*(.*?)\*\//, ""). # remove comments
|
30
|
-
gsub(/\} /, "}\n"). # add line breaks
|
31
|
-
gsub(/\n$/, ""). # remove last break
|
32
|
-
gsub(/ \{ /, " {"). # trim inside brackets
|
33
|
-
gsub(/; \}/, "}") # trim inside brackets
|
34
|
-
end
|
35
|
-
|
36
27
|
|
37
28
|
protected
|
38
29
|
|
data/lib/dynamic_assets.rb
CHANGED
@@ -3,67 +3,162 @@ require 'spec_helper'
|
|
3
3
|
describe DynamicAssetsHelpers do
|
4
4
|
|
5
5
|
describe "#stylesheet_asset_tag" do
|
6
|
-
subject { helper.stylesheet_asset_tag
|
6
|
+
subject { helper.stylesheet_asset_tag *args }
|
7
7
|
|
8
|
-
context "when
|
9
|
-
let(:
|
8
|
+
context "when called with no arguments" do
|
9
|
+
let(:args) { [] }
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
and_return [
|
14
|
-
double(DynamicAssets::Reference, :name => "a", :mtime => 123),
|
15
|
-
double(DynamicAssets::Reference, :name => "b", :mtime => 456),
|
16
|
-
double(DynamicAssets::Reference, :name => "c", :mtime => 789)
|
17
|
-
]
|
11
|
+
it "fails with an ArgumentError" do
|
12
|
+
expect { subject }.to raise_error ArgumentError
|
18
13
|
end
|
14
|
+
end
|
19
15
|
|
20
|
-
|
21
|
-
|
22
|
-
|
16
|
+
context "when called with a group_key" do
|
17
|
+
let(:args) { [group_key] }
|
18
|
+
let(:group_key) { :base }
|
23
19
|
|
24
|
-
|
25
|
-
|
26
|
-
|
20
|
+
context "when the DynamicAssets::Manager says the given group key is associated with 3 stylesheets" do
|
21
|
+
|
22
|
+
before do
|
23
|
+
DynamicAssets::Manager.stub(:asset_references_for_group_key).with(:stylesheets, group_key).
|
24
|
+
and_return [
|
25
|
+
DynamicAssets::StylesheetReference.new.tap { |r| r.stub(:name => "a", :mtime => 123) },
|
26
|
+
DynamicAssets::StylesheetReference.new.tap { |r| r.stub(:name => "b", :mtime => 456) },
|
27
|
+
DynamicAssets::StylesheetReference.new.tap { |r| r.stub(:name => "c", :mtime => 789) }
|
28
|
+
]
|
29
|
+
end
|
30
|
+
|
31
|
+
it "is three link tags" do
|
32
|
+
subject.scan('<link ').length.should == 3
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'is three tags with type="text/css"' do
|
36
|
+
subject.scan('type="text/css"').length.should == 3
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'is three tags with rel"stylesheet"' do
|
40
|
+
subject.scan('rel="stylesheet"').length.should == 3
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'is three tags with media="screen"' do
|
44
|
+
subject.scan('media="screen"').length.should == 3
|
45
|
+
end
|
46
|
+
|
47
|
+
context "when the arguments also include HTML attributes" do
|
48
|
+
before { args << { :media => "print", :id => "foo" } }
|
49
|
+
|
50
|
+
it "is three links, each of which has the given attributes" do
|
51
|
+
subject.scan('media="print"').length.should == 3
|
52
|
+
subject.scan('id="foo"').length.should == 3
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context "when config.asset_host is nil" do
|
57
|
+
before { helper.config.asset_host.should be_nil }
|
58
|
+
|
59
|
+
it "is three tags with hrefs derived from the asset name and mtime" do
|
60
|
+
should contain_string 'href="/assets/stylesheets/a.css?123"'
|
61
|
+
should contain_string 'href="/assets/stylesheets/b.css?456"'
|
62
|
+
should contain_string 'href="/assets/stylesheets/c.css?789"'
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
context "when config.asset_host is set to a.example.com" do
|
67
|
+
before { helper.config.stub(:asset_host).and_return "http://a.example.com" }
|
68
|
+
|
69
|
+
it "is three tags with hrefs whose host is a.example.com" do
|
70
|
+
should contain_string 'href="http://a.example.com/assets/stylesheets/a.css?123"'
|
71
|
+
should contain_string 'href="http://a.example.com/assets/stylesheets/b.css?456"'
|
72
|
+
should contain_string 'href="http://a.example.com/assets/stylesheets/c.css?789"'
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context "when config.asset_host is set to a%d.example.com" do
|
77
|
+
before { helper.config.stub(:asset_host).and_return "http://a%d.example.com" }
|
27
78
|
|
28
|
-
|
29
|
-
|
79
|
+
it "is three tags with hrefs whose host is a[0-3].example.com" do
|
80
|
+
should =~ /href="http:\/\/a[0-3].example.com\/assets\/stylesheets\/a.css\?123"/
|
81
|
+
should =~ /href="http:\/\/a[0-3].example.com\/assets\/stylesheets\/b.css\?456"/
|
82
|
+
should =~ /href="http:\/\/a[0-3].example.com\/assets\/stylesheets\/c.css\?789"/
|
83
|
+
end
|
84
|
+
end
|
30
85
|
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe "#javascript_asset_tag" do
|
90
|
+
subject { helper.javascript_asset_tag *args }
|
31
91
|
|
32
|
-
|
33
|
-
|
92
|
+
context "when called with no arguments" do
|
93
|
+
let(:args) { [] }
|
94
|
+
|
95
|
+
it "fails with an ArgumentError" do
|
96
|
+
expect { subject }.to raise_error ArgumentError
|
34
97
|
end
|
98
|
+
end
|
99
|
+
|
100
|
+
context "when called with a group_key" do
|
101
|
+
let(:args) { [group_key] }
|
102
|
+
let(:group_key) { :base }
|
35
103
|
|
36
|
-
context "when
|
37
|
-
before { helper.config.asset_host.should be_nil }
|
104
|
+
context "when the DynamicAssets::Manager says the given group key is associated with 3 scripts" do
|
38
105
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
106
|
+
before do
|
107
|
+
DynamicAssets::Manager.stub(:asset_references_for_group_key).with(:javascripts, group_key).
|
108
|
+
and_return [
|
109
|
+
DynamicAssets::JavascriptReference.new.tap { |r| r.stub(:name => "a", :mtime => 123) },
|
110
|
+
DynamicAssets::JavascriptReference.new.tap { |r| r.stub(:name => "b", :mtime => 456) },
|
111
|
+
DynamicAssets::JavascriptReference.new.tap { |r| r.stub(:name => "c", :mtime => 789) }
|
112
|
+
]
|
43
113
|
end
|
44
|
-
end
|
45
114
|
|
46
|
-
|
47
|
-
|
115
|
+
it "is three script tags" do
|
116
|
+
subject.scan('<script ').length.should == 3
|
117
|
+
end
|
48
118
|
|
49
|
-
it
|
50
|
-
|
51
|
-
|
52
|
-
|
119
|
+
it 'is three tags with type="text/javascript"' do
|
120
|
+
subject.scan('type="text/javascript"').length.should == 3
|
121
|
+
end
|
122
|
+
|
123
|
+
context "when the arguments also include HTML attributes" do
|
124
|
+
before { args << { :id => "foo" } }
|
125
|
+
|
126
|
+
it "is three links, each of which has the given attributes" do
|
127
|
+
subject.scan('id="foo"').length.should == 3
|
128
|
+
end
|
53
129
|
end
|
54
|
-
end
|
55
130
|
|
56
|
-
|
57
|
-
|
131
|
+
context "when config.asset_host is nil" do
|
132
|
+
before { helper.config.asset_host.should be_nil }
|
58
133
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
134
|
+
it "is three tags with srcs derived from the asset name and mtime" do
|
135
|
+
should contain_string 'src="/assets/javascripts/a.js?123"'
|
136
|
+
should contain_string 'src="/assets/javascripts/b.js?456"'
|
137
|
+
should contain_string 'src="/assets/javascripts/c.js?789"'
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
context "when config.asset_host is set to a.example.com" do
|
142
|
+
before { helper.config.stub(:asset_host).and_return "http://a.example.com" }
|
143
|
+
|
144
|
+
it "is three tags with srcs whose host is a.example.com" do
|
145
|
+
should contain_string 'src="http://a.example.com/assets/javascripts/a.js?123"'
|
146
|
+
should contain_string 'src="http://a.example.com/assets/javascripts/b.js?456"'
|
147
|
+
should contain_string 'src="http://a.example.com/assets/javascripts/c.js?789"'
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
context "when config.asset_host is set to a%d.example.com" do
|
152
|
+
before { helper.config.stub(:asset_host).and_return "http://a%d.example.com" }
|
153
|
+
|
154
|
+
it "is three tags with srcs whose host is a[0-3].example.com" do
|
155
|
+
should =~ /src="http:\/\/a[0-3].example.com\/assets\/javascripts\/a.js\?123"/
|
156
|
+
should =~ /src="http:\/\/a[0-3].example.com\/assets\/javascripts\/b.js\?456"/
|
157
|
+
should =~ /src="http:\/\/a[0-3].example.com\/assets\/javascripts\/c.js\?789"/
|
158
|
+
end
|
63
159
|
end
|
64
160
|
end
|
65
161
|
end
|
66
|
-
|
67
162
|
end
|
68
163
|
|
69
164
|
end
|
@@ -10,18 +10,44 @@ module DynamicAssets
|
|
10
10
|
context "when a css file with the given reference name exists" do
|
11
11
|
before do
|
12
12
|
reference.stub(:path_for_member_name).with("thing").and_return "/foo/thing.css"
|
13
|
-
reference.stub(:raw_content_exists?).and_return false
|
14
13
|
reference.stub(:raw_content_exists?).with("/foo/thing.css").and_return true
|
15
|
-
reference.stub(:get_raw_content).with("/foo/thing.css").and_return
|
14
|
+
reference.stub(:get_raw_content).with("/foo/thing.css").and_return raw_content
|
16
15
|
end
|
17
16
|
|
18
17
|
context "and the file is blank" do
|
19
|
-
let(:
|
18
|
+
let(:raw_content) { "" }
|
20
19
|
it { should be_blank }
|
21
20
|
end
|
22
21
|
|
22
|
+
context "and the file contains styles" do
|
23
|
+
let(:raw_content) { "div.foo { color: #FFF }" }
|
24
|
+
|
25
|
+
context "and the Manager is not configured to minify" do
|
26
|
+
before { Manager.stub :minify? => false }
|
27
|
+
|
28
|
+
it "is the raw content" do
|
29
|
+
subject.should == raw_content
|
30
|
+
end
|
31
|
+
|
32
|
+
it "does not call its own #minify method" do
|
33
|
+
reference.should_not_receive :minify
|
34
|
+
subject
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context "and the Manager is configured to minify" do
|
39
|
+
before { Manager.stub :minify? => true }
|
40
|
+
|
41
|
+
it "is the result of calling its own #minify method" do
|
42
|
+
reference.should_receive(:minify).and_return "tiny output"
|
43
|
+
subject.should == "tiny output"
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
23
49
|
context "and the file contains URLs relative to the stylesheet" do
|
24
|
-
let(:
|
50
|
+
let(:raw_content) { "body { background: url(background.gif); }" }
|
25
51
|
|
26
52
|
it "makes the URLs relative to RELATIVE_URL_ROOT and the member name" do
|
27
53
|
should contain_string "url(#{StylesheetReference::RELATIVE_URL_ROOT}/thing/background.gif)"
|
@@ -29,7 +55,7 @@ module DynamicAssets
|
|
29
55
|
end
|
30
56
|
|
31
57
|
context "and the file contains URLs within directories relative to the stylesheet" do
|
32
|
-
let(:
|
58
|
+
let(:raw_content) { "body { background: url(a/b/background.gif); }" }
|
33
59
|
|
34
60
|
it "makes the URLs relative to RELATIVE_URL_ROOT and the member name" do
|
35
61
|
should contain_string "url(#{StylesheetReference::RELATIVE_URL_ROOT}/thing/a/b/background.gif)"
|
@@ -37,7 +63,7 @@ module DynamicAssets
|
|
37
63
|
end
|
38
64
|
|
39
65
|
context "and the file contains URLs with dots, relative to the stylesheet" do
|
40
|
-
let(:
|
66
|
+
let(:raw_content) { "body { background: url(../a/b/background.gif); }" }
|
41
67
|
|
42
68
|
it "makes the URLs relative to RELATIVE_URL_ROOT and the member name, ignoring leading dots" do
|
43
69
|
should contain_string "url(#{StylesheetReference::RELATIVE_URL_ROOT}/thing/a/b/background.gif)"
|
@@ -45,7 +71,7 @@ module DynamicAssets
|
|
45
71
|
end
|
46
72
|
|
47
73
|
context "and the file contains full URLs with hosts" do
|
48
|
-
let(:
|
74
|
+
let(:raw_content) { "body { background: url(http://www.example.com/background.gif); }" }
|
49
75
|
|
50
76
|
it "leaves the URLs unchanged" do
|
51
77
|
should contain_string "url(http://www.example.com/background.gif)"
|
@@ -54,5 +80,60 @@ module DynamicAssets
|
|
54
80
|
end
|
55
81
|
end
|
56
82
|
|
83
|
+
describe "#minify" do
|
84
|
+
subject { reference.minify content }
|
85
|
+
let(:reference) { StylesheetReference.new :name => "thing" }
|
86
|
+
|
87
|
+
context "when given content that has whitespace and comments" do
|
88
|
+
let(:content) do %Q!
|
89
|
+
/*
|
90
|
+
* Some sample styles
|
91
|
+
*/
|
92
|
+
div.foo { color: #FFF; } /* foo style */
|
93
|
+
div.bar, span.baz { font-size: 12px; }
|
94
|
+
!
|
95
|
+
end
|
96
|
+
|
97
|
+
it "is the result of calling CSSMin.minify" do
|
98
|
+
CSSMin.should_receive(:minify).with(content).and_return "tiny content"
|
99
|
+
subject.should == "tiny content"
|
100
|
+
end
|
101
|
+
|
102
|
+
# We assume CSSMin is fully tested, but as a sanity check we
|
103
|
+
# observe the StylesheetReference's behavior with a few examples:
|
104
|
+
|
105
|
+
it "contains no double spaces" do
|
106
|
+
should_not =~ / /
|
107
|
+
end
|
108
|
+
|
109
|
+
it "contains no newlines" do
|
110
|
+
should_not =~ /\n/
|
111
|
+
end
|
112
|
+
|
113
|
+
it "removes space between selectors" do
|
114
|
+
should contain_string "div.bar,span.baz"
|
115
|
+
end
|
116
|
+
|
117
|
+
it "removes space around opening brackets" do
|
118
|
+
should contain_string "span.baz{font-size"
|
119
|
+
end
|
120
|
+
|
121
|
+
it "removes space around closing brackets" do
|
122
|
+
should contain_string "}div.bar"
|
123
|
+
end
|
124
|
+
|
125
|
+
it "removes space around values" do
|
126
|
+
should contain_string "font-size:12px;}"
|
127
|
+
end
|
128
|
+
|
129
|
+
it "removes comments that are on their own lines" do
|
130
|
+
should_not contain_string "Some sample styles"
|
131
|
+
end
|
132
|
+
|
133
|
+
it "removes comments that are on the same line as a style" do
|
134
|
+
should_not contain_string "Some sample styles"
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
57
138
|
end
|
58
139
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -6,10 +6,7 @@ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
|
6
6
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
7
7
|
|
8
8
|
require 'rspec/rails'
|
9
|
-
|
10
|
-
require "capybara/rails"
|
11
|
-
Capybara.default_driver = :rack_test
|
12
|
-
Capybara.default_selector = :css
|
9
|
+
require 'capybara/rspec'
|
13
10
|
|
14
11
|
require 'dynamic_assets'
|
15
12
|
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dynamic_assets
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 19
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
8
|
+
- 3
|
9
9
|
- 0
|
10
|
-
version: 0.
|
10
|
+
version: 0.3.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Robert Davis
|
@@ -128,6 +128,7 @@ files:
|
|
128
128
|
- lib/dynamic_assets/config.rb
|
129
129
|
- lib/dynamic_assets/controller.rb
|
130
130
|
- lib/dynamic_assets/core_extensions.rb
|
131
|
+
- lib/dynamic_assets/cssmin.rb
|
131
132
|
- lib/dynamic_assets/engine.rb
|
132
133
|
- lib/dynamic_assets/manager.rb
|
133
134
|
- lib/dynamic_assets/reference.rb
|