asset-trip 0.1.0
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.
- data/.gitignore +2 -0
- data/History.txt +6 -0
- data/MIT-LICENSE.txt +19 -0
- data/README.rdoc +27 -0
- data/Rakefile +12 -0
- data/Thorfile +110 -0
- data/asset-trip.gemspec +107 -0
- data/init.rb +3 -0
- data/lib/asset_trip/asset.rb +82 -0
- data/lib/asset_trip/compressor.rb +36 -0
- data/lib/asset_trip/config.rb +60 -0
- data/lib/asset_trip/file_writer.rb +17 -0
- data/lib/asset_trip/helper.rb +83 -0
- data/lib/asset_trip/javascript.rb +29 -0
- data/lib/asset_trip/load_path.rb +39 -0
- data/lib/asset_trip/manifest.rb +40 -0
- data/lib/asset_trip/manifest_writer.rb +35 -0
- data/lib/asset_trip/memoizable.rb +28 -0
- data/lib/asset_trip/middleware.rb +109 -0
- data/lib/asset_trip/ssl_stylesheet.rb +15 -0
- data/lib/asset_trip/stylesheet.rb +44 -0
- data/lib/asset_trip/url_rewriter.rb +82 -0
- data/lib/asset_trip.rb +66 -0
- data/spec/asset_trip/asset_spec.rb +47 -0
- data/spec/asset_trip/compressor_spec.rb +46 -0
- data/spec/asset_trip/config_spec.rb +61 -0
- data/spec/asset_trip/helper_spec.rb +221 -0
- data/spec/asset_trip/javascript_spec.rb +24 -0
- data/spec/asset_trip/load_path_spec.rb +61 -0
- data/spec/asset_trip/manifest_writer_spec.rb +32 -0
- data/spec/asset_trip/middleware_spec.rb +72 -0
- data/spec/asset_trip/stylesheet_spec.rb +51 -0
- data/spec/asset_trip/url_rewriter_spec.rb +166 -0
- data/spec/asset_trip_spec.rb +13 -0
- data/spec/fixtures/app/javascripts/main/new.js +1 -0
- data/spec/fixtures/app/javascripts/main.js +1 -0
- data/spec/fixtures/app/javascripts/signup.js +1 -0
- data/spec/fixtures/app/stylesheets/new.css +0 -0
- data/spec/fixtures/config/asset_trip/assets.rb +0 -0
- data/spec/integration/bundle_spec.rb +243 -0
- data/spec/integration/prune_spec.rb +53 -0
- data/spec/spec.opts +3 -0
- data/spec/spec_helper.rb +24 -0
- data/spec/support/core_extensions.rb +13 -0
- data/spec/support/helpers.rb +33 -0
- data/spec/support/matchers.rb +67 -0
- data/spec/support/path_utils.rb +45 -0
- data/spec/support/sandbox_helper.rb +19 -0
- data/tasks/asset_trip.rake +11 -0
- data/vendor/yuicompressor-2.4.2.jar +0 -0
- metadata +128 -0
@@ -0,0 +1,221 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "action_controller"
|
3
|
+
require "action_view"
|
4
|
+
|
5
|
+
describe AssetTrip::Helper do
|
6
|
+
include ActionView::Helpers::TagHelper
|
7
|
+
include ActionView::Helpers::AssetTagHelper
|
8
|
+
include AssetTrip::Helper
|
9
|
+
|
10
|
+
before do
|
11
|
+
# Silence ruby -W warning triggered inside asset_tag_helper.rb
|
12
|
+
@controller = nil
|
13
|
+
end
|
14
|
+
|
15
|
+
let(:request) { stub(:host => "localhost.com", :ssl? => false, :protocol => "http://", :port => 80) }
|
16
|
+
|
17
|
+
describe "#javascript_include_asset" do
|
18
|
+
it "generates a <script> tag based on the Manifest" do
|
19
|
+
AssetTrip.stub!(:manifest => AssetTrip::Manifest.new("foo.js" => "884695aafa07bf0c3e1f1fe578dd10d0"))
|
20
|
+
javascript_include_asset("foo").should be_like(<<-HTML)
|
21
|
+
<script src="/assets/88/4695aafa0/foo.js" type="text/javascript"></script>
|
22
|
+
HTML
|
23
|
+
end
|
24
|
+
|
25
|
+
it "generates multiple <script> tags" do
|
26
|
+
AssetTrip.stub!(:manifest => AssetTrip::Manifest.new(
|
27
|
+
"foo.js" => "884695aafa07bf0c3e1f1fe578dd10d0",
|
28
|
+
"bar.js" => "1349f22e9bd188ef71503ba80624fc68"))
|
29
|
+
javascript_include_asset("foo", "bar").should be_like(<<-HTML)
|
30
|
+
<script src="/assets/88/4695aafa0/foo.js" type="text/javascript"></script>
|
31
|
+
<script src="/assets/13/49f22e9bd/bar.js" type="text/javascript"></script>
|
32
|
+
HTML
|
33
|
+
end
|
34
|
+
|
35
|
+
it "works with the file extension specified" do
|
36
|
+
AssetTrip.stub!(:manifest => AssetTrip::Manifest.new("foo.js" => "884695aafa07bf0c3e1f1fe578dd10d0"))
|
37
|
+
javascript_include_asset("foo.js").should be_like(<<-HTML)
|
38
|
+
<script src="/assets/88/4695aafa0/foo.js" type="text/javascript"></script>
|
39
|
+
HTML
|
40
|
+
end
|
41
|
+
|
42
|
+
it "works with symbols" do
|
43
|
+
AssetTrip.stub!(:manifest => AssetTrip::Manifest.new("foo.js" => "884695aafa07bf0c3e1f1fe578dd10d0"))
|
44
|
+
javascript_include_asset(:foo).should be_like(<<-HTML)
|
45
|
+
<script src="/assets/88/4695aafa0/foo.js" type="text/javascript"></script>
|
46
|
+
HTML
|
47
|
+
end
|
48
|
+
|
49
|
+
it "raises an UnknownAssetError if it's not in the manifest" do
|
50
|
+
AssetTrip.stub!(:manifest => AssetTrip::Manifest.new)
|
51
|
+
lambda {
|
52
|
+
javascript_include_asset("foo")
|
53
|
+
}.should raise_error(AssetTrip::UnknownAssetError)
|
54
|
+
end
|
55
|
+
|
56
|
+
it "does not add file mtimes into the query string" do
|
57
|
+
AssetTrip.stub!(:manifest => AssetTrip::Manifest.new("foo.js" => "884695aafa07bf0c3e1f1fe578dd10d0"))
|
58
|
+
stub!(:rails_asset_id => "rails_asset_id")
|
59
|
+
javascript_include_asset("foo").should_not include("rails_asset_id")
|
60
|
+
end
|
61
|
+
|
62
|
+
it "does not prevent mtimes from being added to other JavaScripts" do
|
63
|
+
stub!(:rails_asset_id => "rails_asset_id")
|
64
|
+
javascript_include_tag("foo").should include("rails_asset_id")
|
65
|
+
end
|
66
|
+
|
67
|
+
it "works" do
|
68
|
+
request.stub!(:ssl? => true)
|
69
|
+
AssetTrip.stub!(:manifest => AssetTrip::Manifest.new("foo.js" => "884695aafa07bf0c3e1f1fe578dd10d0"))
|
70
|
+
javascript_include_asset("foo").should be_like(<<-HTML)
|
71
|
+
<script src="/assets/88/4695aafa0/foo.js" type="text/javascript"></script>
|
72
|
+
HTML
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe "#stylesheet_link_asset" do
|
77
|
+
it "generates a <style> tag based on the manifest" do
|
78
|
+
AssetTrip.stub!(:manifest => AssetTrip::Manifest.new("foo.css" => "884695aafa07bf0c3e1f1fe578dd10d0"))
|
79
|
+
stylesheet_link_asset("foo").should be_like(<<-HTML)
|
80
|
+
<link href="/assets/88/4695aafa0/foo.css" media="screen" rel="stylesheet" type="text/css" />
|
81
|
+
HTML
|
82
|
+
end
|
83
|
+
|
84
|
+
it "generates multiple <style> tags" do
|
85
|
+
AssetTrip.stub!(:manifest => AssetTrip::Manifest.new(
|
86
|
+
"foo.css" => "884695aafa07bf0c3e1f1fe578dd10d0",
|
87
|
+
"bar.css" => "1349f22e9bd188ef71503ba80624fc68"))
|
88
|
+
stylesheet_link_asset("foo", "bar").should be_like(<<-HTML)
|
89
|
+
<link href="/assets/88/4695aafa0/foo.css" media="screen" rel="stylesheet" type="text/css" />
|
90
|
+
<link href="/assets/13/49f22e9bd/bar.css" media="screen" rel="stylesheet" type="text/css" />
|
91
|
+
HTML
|
92
|
+
end
|
93
|
+
|
94
|
+
it "supports passing options through to stylesheet_link_tag" do
|
95
|
+
AssetTrip.stub!(:manifest => AssetTrip::Manifest.new("foo.css" => "884695aafa07bf0c3e1f1fe578dd10d0"))
|
96
|
+
stylesheet_link_asset("foo", :media => "print").should be_like(<<-HTML)
|
97
|
+
<link href="/assets/88/4695aafa0/foo.css" media="print" rel="stylesheet" type="text/css" />
|
98
|
+
HTML
|
99
|
+
end
|
100
|
+
|
101
|
+
it "works with the file extension specified" do
|
102
|
+
AssetTrip.stub!(:manifest => AssetTrip::Manifest.new("foo.css" => "884695aafa07bf0c3e1f1fe578dd10d0"))
|
103
|
+
stylesheet_link_asset("foo.css").should be_like(<<-HTML)
|
104
|
+
<link href="/assets/88/4695aafa0/foo.css" media="screen" rel="stylesheet" type="text/css" />
|
105
|
+
HTML
|
106
|
+
end
|
107
|
+
|
108
|
+
it "works with symbols" do
|
109
|
+
AssetTrip.stub!(:manifest => AssetTrip::Manifest.new("foo.css" => "884695aafa07bf0c3e1f1fe578dd10d0"))
|
110
|
+
stylesheet_link_asset(:foo).should be_like(<<-HTML)
|
111
|
+
<link href="/assets/88/4695aafa0/foo.css" media="screen" rel="stylesheet" type="text/css" />
|
112
|
+
HTML
|
113
|
+
end
|
114
|
+
|
115
|
+
it "raises an UnknownAssetError if it's not in the manifest" do
|
116
|
+
AssetTrip.stub!(:manifest => AssetTrip::Manifest.new)
|
117
|
+
lambda {
|
118
|
+
stylesheet_link_asset("foo")
|
119
|
+
}.should raise_error(AssetTrip::UnknownAssetError)
|
120
|
+
end
|
121
|
+
|
122
|
+
it "does not add file mtimes into the query string" do
|
123
|
+
AssetTrip.stub!(:manifest => AssetTrip::Manifest.new("foo.css" => "884695aafa07bf0c3e1f1fe578dd10d0"))
|
124
|
+
stub!(:rails_asset_id => "rails_asset_id")
|
125
|
+
stylesheet_link_asset("foo").should_not include("rails_asset_id")
|
126
|
+
end
|
127
|
+
|
128
|
+
it "does not prevent mtimes from being added to other JavaScripts" do
|
129
|
+
stub!(:rails_asset_id => "rails_asset_id")
|
130
|
+
stylesheet_link_tag("foo").should include("rails_asset_id")
|
131
|
+
end
|
132
|
+
|
133
|
+
it "generates a link to the SSL version when necessary" do
|
134
|
+
request.stub!(:ssl? => true)
|
135
|
+
|
136
|
+
AssetTrip.stub!(:manifest => AssetTrip::Manifest.new("foo.ssl.css" => "884695aafa07bf0c3e1f1fe578dd10d0"))
|
137
|
+
stylesheet_link_asset("foo").should be_like(<<-HTML)
|
138
|
+
<link href="/assets/88/4695aafa0/foo.ssl.css" media="screen" rel="stylesheet" type="text/css" />
|
139
|
+
HTML
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
context "when bundling is disabled" do
|
144
|
+
it "generates links to the unbundled Javascripts" do
|
145
|
+
AssetTrip.stub!(:bundle => false)
|
146
|
+
|
147
|
+
config = AssetTrip::Config.new do
|
148
|
+
js_asset "foo" do
|
149
|
+
include "first"
|
150
|
+
include "second"
|
151
|
+
end
|
152
|
+
end
|
153
|
+
AssetTrip.stub!(:config => config)
|
154
|
+
|
155
|
+
javascript_include_asset("foo").should be_like(<<-HTML)
|
156
|
+
<script src="http://localhost.com:80/__asset_trip__/javascripts/first.js" type="text/javascript"></script>
|
157
|
+
<script src="http://localhost.com:80/__asset_trip__/javascripts/second.js" type="text/javascript"></script>
|
158
|
+
HTML
|
159
|
+
end
|
160
|
+
|
161
|
+
it "generates links to the unbundled Stylesheets" do
|
162
|
+
AssetTrip.stub!(:bundle => false)
|
163
|
+
|
164
|
+
config = AssetTrip::Config.new do
|
165
|
+
css_asset "all" do
|
166
|
+
include "fonts"
|
167
|
+
include "colors"
|
168
|
+
end
|
169
|
+
end
|
170
|
+
AssetTrip.stub!(:config => config)
|
171
|
+
|
172
|
+
stylesheet_link_asset("all").should be_like(<<-HTML)
|
173
|
+
<link href="http://localhost.com:80/__asset_trip__/stylesheets/fonts.css" media="screen" rel="stylesheet" type="text/css" />
|
174
|
+
<link href="http://localhost.com:80/__asset_trip__/stylesheets/colors.css" media="screen" rel="stylesheet" type="text/css" />
|
175
|
+
HTML
|
176
|
+
end
|
177
|
+
|
178
|
+
context "when serving an https request" do
|
179
|
+
before do
|
180
|
+
request.stub!(:ssl? => true, :protocol => "https://")
|
181
|
+
end
|
182
|
+
|
183
|
+
it "generates ssl links to the unbundled Stylesheets" do
|
184
|
+
AssetTrip.stub!(:bundle => false)
|
185
|
+
|
186
|
+
config = AssetTrip::Config.new do
|
187
|
+
css_asset "all" do
|
188
|
+
include "fonts"
|
189
|
+
include "colors"
|
190
|
+
end
|
191
|
+
end
|
192
|
+
AssetTrip.stub!(:config => config)
|
193
|
+
|
194
|
+
stylesheet_link_asset("all").should be_like(<<-HTML)
|
195
|
+
<link href="https://localhost.com:80/__asset_trip__/stylesheets/fonts.css" media="screen" rel="stylesheet" type="text/css" />
|
196
|
+
<link href="https://localhost.com:80/__asset_trip__/stylesheets/colors.css" media="screen" rel="stylesheet" type="text/css" />
|
197
|
+
HTML
|
198
|
+
end
|
199
|
+
|
200
|
+
it "generates ssl links to the unbundled Javascripts" do
|
201
|
+
AssetTrip.stub!(:bundle => false)
|
202
|
+
|
203
|
+
config = AssetTrip::Config.new do
|
204
|
+
js_asset "foo" do
|
205
|
+
include "first"
|
206
|
+
include "second"
|
207
|
+
end
|
208
|
+
end
|
209
|
+
AssetTrip.stub!(:config => config)
|
210
|
+
|
211
|
+
javascript_include_asset("foo").should be_like(<<-HTML)
|
212
|
+
<script src="https://localhost.com:80/__asset_trip__/javascripts/first.js" type="text/javascript"></script>
|
213
|
+
<script src="https://localhost.com:80/__asset_trip__/javascripts/second.js" type="text/javascript"></script>
|
214
|
+
HTML
|
215
|
+
end
|
216
|
+
|
217
|
+
end
|
218
|
+
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe AssetTrip::Javascript do
|
4
|
+
describe "#contents" do
|
5
|
+
before do
|
6
|
+
AssetTrip::Compressor.stub!(:new => compressor)
|
7
|
+
File.stub!(:read => "contents")
|
8
|
+
end
|
9
|
+
|
10
|
+
let(:compressor) { stub(:compress => "compressed") }
|
11
|
+
|
12
|
+
it "compresses the contents" do
|
13
|
+
AssetTrip::Compressor.should_receive(:new).with("js")
|
14
|
+
asset = AssetTrip::Javascript.new(stub(), "all.css")
|
15
|
+
asset.contents.should == "compressed"
|
16
|
+
end
|
17
|
+
|
18
|
+
it "only runs the Compressor once for the package" do
|
19
|
+
compressor.should_receive(:compress).exactly(:once)
|
20
|
+
asset = AssetTrip::Javascript.new(stub(), "all.css")
|
21
|
+
asset.contents.should == "compressed"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe AssetTrip::LoadPath do
|
4
|
+
describe "#==" do
|
5
|
+
it "is not equal to other classes" do
|
6
|
+
AssetTrip::LoadPath.new.should_not == String.new
|
7
|
+
end
|
8
|
+
|
9
|
+
it "is not equal to LoadPaths with different paths" do
|
10
|
+
AssetTrip::LoadPath.new(["app/javascripts"]).should_not ==
|
11
|
+
AssetTrip::LoadPath.new(["app/stylesheets"])
|
12
|
+
end
|
13
|
+
|
14
|
+
it "is equal to LoadPaths with the same paths" do
|
15
|
+
AssetTrip::LoadPath.new(["app/javascripts"]).should ==
|
16
|
+
AssetTrip::LoadPath.new(["app/javascripts"])
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "#<<" do
|
21
|
+
it "appends strings as Pathnames" do
|
22
|
+
load_path = AssetTrip::LoadPath.new
|
23
|
+
load_path << "app/javascripts"
|
24
|
+
load_path.should == AssetTrip::LoadPath.new([Pathname.new("app/javascripts")])
|
25
|
+
end
|
26
|
+
|
27
|
+
it "appends Pathnames" do
|
28
|
+
load_path = AssetTrip::LoadPath.new
|
29
|
+
load_path << Pathname.new("app/javascripts")
|
30
|
+
load_path.should == AssetTrip::LoadPath.new([Pathname.new("app/javascripts")])
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "#resolve" do
|
35
|
+
it "returns an absolute path to an existing file" do
|
36
|
+
File.stub!(:exist? => true)
|
37
|
+
load_path = AssetTrip::LoadPath.new(["/"])
|
38
|
+
load_path.resolve("found.css").should == Pathname.new("/found.css")
|
39
|
+
end
|
40
|
+
|
41
|
+
it "prefers finding files in earlier paths to later paths" do
|
42
|
+
File.stub!(:exist? => true)
|
43
|
+
load_path = AssetTrip::LoadPath.new(["/usr", "/"])
|
44
|
+
load_path.resolve("found.css").should == Pathname.new("/usr/found.css")
|
45
|
+
end
|
46
|
+
|
47
|
+
it "raises an UnknownAssetError when resolving nil" do
|
48
|
+
load_path = AssetTrip::LoadPath.new
|
49
|
+
lambda {
|
50
|
+
load_path.resolve(nil)
|
51
|
+
}.should raise_error(AssetTrip::UnknownAssetError)
|
52
|
+
end
|
53
|
+
|
54
|
+
it "raises an UnknownAssetError when the file is not found" do
|
55
|
+
load_path = AssetTrip::LoadPath.new
|
56
|
+
lambda {
|
57
|
+
load_path.resolve("missing.jpg")
|
58
|
+
}.should raise_error(AssetTrip::UnknownAssetError)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe AssetTrip::ManifestWriter do
|
4
|
+
describe "#write!" do
|
5
|
+
it "writes a Ruby file" do
|
6
|
+
path = AssetTrip.app_root.join("config", "asset_trip", "manifest.rb")
|
7
|
+
AssetTrip::FileWriter.should_receive(:new).with(path).and_return(stub(:write! => nil))
|
8
|
+
manifest_writer = AssetTrip::ManifestWriter.new([])
|
9
|
+
manifest_writer.write!
|
10
|
+
end
|
11
|
+
|
12
|
+
it "initializes @manifest in AssetTrip to be a hash" do
|
13
|
+
file_writer = stub
|
14
|
+
file_writer.should_receive(:write!).with(<<-SRC)
|
15
|
+
module AssetTrip
|
16
|
+
@manifest = Manifest.new
|
17
|
+
end
|
18
|
+
SRC
|
19
|
+
AssetTrip::FileWriter.stub!(:new => file_writer)
|
20
|
+
manifest_writer = AssetTrip::ManifestWriter.new([])
|
21
|
+
manifest_writer.write!
|
22
|
+
end
|
23
|
+
|
24
|
+
it "stores the MD5 of each asset as the value in the hash" do
|
25
|
+
file_writer = stub
|
26
|
+
file_writer.should_receive(:write!).with(/@manifest\["foo.js"\] = "fa9bac2ae2d"/)
|
27
|
+
AssetTrip::FileWriter.stub!(:new => file_writer)
|
28
|
+
manifest_writer = AssetTrip::ManifestWriter.new([stub(:asset, :name => "foo.js", :md5sum => "fa9bac2ae2d19ec2942a718253c55862")])
|
29
|
+
manifest_writer.write!
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "rack/test"
|
3
|
+
|
4
|
+
describe AssetTrip::Middleware do
|
5
|
+
include Rack::Test::Methods
|
6
|
+
|
7
|
+
setup_sandbox_app!
|
8
|
+
|
9
|
+
def app
|
10
|
+
AssetTrip::Middleware.new(lambda {
|
11
|
+
[404, {"Content-Type" => "text/html"}, ["Not Found"]]
|
12
|
+
})
|
13
|
+
end
|
14
|
+
|
15
|
+
it "calls down the chain if the URL root is not known" do
|
16
|
+
response = get "/"
|
17
|
+
response.should be_not_found
|
18
|
+
end
|
19
|
+
|
20
|
+
it "404s if the URL root matches but there is no subdirectory" do
|
21
|
+
response = get "/__asset_trip__/not_found.js"
|
22
|
+
response.should be_not_found
|
23
|
+
end
|
24
|
+
|
25
|
+
it "404s if the URL root is known but it can't find the file" do
|
26
|
+
response = get "/__asset_trip__/javascripts/not_found.js"
|
27
|
+
response.should be_not_found
|
28
|
+
end
|
29
|
+
|
30
|
+
it "serves Javascripts" do
|
31
|
+
response = get "/__asset_trip__/javascripts/main.js"
|
32
|
+
response.should be_ok
|
33
|
+
end
|
34
|
+
|
35
|
+
it "serves Stylesheets" do
|
36
|
+
response = get "/__asset_trip__/stylesheets/new.css"
|
37
|
+
response.should be_ok
|
38
|
+
end
|
39
|
+
|
40
|
+
it "sets the Last-Modified header" do
|
41
|
+
path = File.join(Dir.pwd, "app", "javascripts", "main.js")
|
42
|
+
response = get "/__asset_trip__/javascripts/main.js"
|
43
|
+
response["Last-Modified"].should == File.mtime(path).httpdate
|
44
|
+
end
|
45
|
+
|
46
|
+
it "does not allow directory traversal" do
|
47
|
+
response = get "/__asset_trip__/../main.js"
|
48
|
+
response.should be_forbidden
|
49
|
+
end
|
50
|
+
|
51
|
+
it "does not allow directory traversal with encoded periods" do
|
52
|
+
response = get "/__asset_trip__/%2E%2E/main.js"
|
53
|
+
response.should be_forbidden
|
54
|
+
end
|
55
|
+
|
56
|
+
it "serves files with URL encoded filenames" do
|
57
|
+
response = get "/__asset_trip__/javascripts/%6D%61%69%6E.js" # main.js
|
58
|
+
response.should be_ok
|
59
|
+
end
|
60
|
+
|
61
|
+
it "serves Javascripts based on the JS load path" do
|
62
|
+
AssetTrip.config.load_paths[:javascripts] = AssetTrip::LoadPath.new
|
63
|
+
response = get "/__asset_trip__/javascripts/main.js"
|
64
|
+
response.should be_not_found
|
65
|
+
end
|
66
|
+
|
67
|
+
it "serves Stylesheets based on the CSS load path" do
|
68
|
+
AssetTrip.config.load_paths[:stylesheets] = AssetTrip::LoadPath.new
|
69
|
+
response = get "/__asset_trip__/stylesheets/new.css"
|
70
|
+
response.should be_not_found
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe AssetTrip::Stylesheet do
|
4
|
+
describe "#contents" do
|
5
|
+
setup_sandbox_app!
|
6
|
+
|
7
|
+
before do
|
8
|
+
AssetTrip::Compressor.stub!(:new => compressor)
|
9
|
+
File.stub!(:read => "contents")
|
10
|
+
end
|
11
|
+
|
12
|
+
let(:compressor) { stub(:compress => "compressed") }
|
13
|
+
let(:url_rewriter) { stub(:rewrite => "rewritten") }
|
14
|
+
|
15
|
+
it "compresses the contents" do
|
16
|
+
AssetTrip::Compressor.should_receive(:new).with("css")
|
17
|
+
asset = AssetTrip::Stylesheet.new(stub(), "all.css")
|
18
|
+
asset.contents.should == "compressed"
|
19
|
+
end
|
20
|
+
|
21
|
+
it "only runs the Compressor once for the package" do
|
22
|
+
compressor.should_receive(:compress).exactly(:once)
|
23
|
+
asset = AssetTrip::Stylesheet.new(stub(), "all.css")
|
24
|
+
asset.contents.should == "compressed"
|
25
|
+
end
|
26
|
+
|
27
|
+
it "rewrites the URLs" do
|
28
|
+
AssetTrip::UrlRewriter.stub(:new => url_rewriter)
|
29
|
+
url_rewriter.should_receive(:rewrite).with("contents")
|
30
|
+
asset = AssetTrip::Stylesheet.new(stub(:resolve_file => "/fonts.css"), "all", ["fonts"])
|
31
|
+
asset.contents
|
32
|
+
end
|
33
|
+
|
34
|
+
context "when the stylesheet is in the public directory" do
|
35
|
+
it "does not initialize the UrlRewriter with a path" do
|
36
|
+
AssetTrip::UrlRewriter.should_receive(:new).with("http").and_return(url_rewriter)
|
37
|
+
asset = AssetTrip::Stylesheet.new(stub(:resolve_file => "/fonts.css"), "all", ["fonts"])
|
38
|
+
asset.contents
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context "when the stylesheet is not in the public directory" do
|
43
|
+
it "initializes the UrlRewriter with a path" do
|
44
|
+
AssetTrip::UrlRewriter.should_receive(:new).with("http", Pathname.new("/fonts.css")).and_return(url_rewriter)
|
45
|
+
public_path = fixture_app.join("public", "fonts.css")
|
46
|
+
asset = AssetTrip::Stylesheet.new(stub(:resolve_file => public_path), "all", ["fonts"])
|
47
|
+
asset.contents
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,166 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "action_controller"
|
3
|
+
|
4
|
+
describe AssetTrip::UrlRewriter do
|
5
|
+
def self.it_rewrites_urls(path, mappings)
|
6
|
+
original = mappings.keys.first
|
7
|
+
result = mappings.values.first
|
8
|
+
|
9
|
+
it "rewriters #{original} to #{result} in #{path}" do
|
10
|
+
output = AssetTrip::UrlRewriter.new("http", Pathname.new(path)).rewrite <<-CSS
|
11
|
+
.foo { background: url(#{original}) }
|
12
|
+
CSS
|
13
|
+
|
14
|
+
output.should include("url(#{result})")
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "#rewrite" do
|
19
|
+
it "applies asset hosts to CSS background images" do
|
20
|
+
ActionController::Base.stub!(:asset_host => "http://cdn.example.com")
|
21
|
+
|
22
|
+
output = AssetTrip::UrlRewriter.new("http").rewrite <<-CSS
|
23
|
+
.foo { background: url(/foo.jpg) }
|
24
|
+
CSS
|
25
|
+
|
26
|
+
output.should include('url(http://cdn.example.com/foo.jpg)')
|
27
|
+
end
|
28
|
+
|
29
|
+
it "rewrites URLs with SSL when configured with SSL" do
|
30
|
+
ActionController::Base.stub!(:asset_host => "http://cdn.example.com")
|
31
|
+
|
32
|
+
output = AssetTrip::UrlRewriter.new("https").rewrite <<-CSS
|
33
|
+
.foo { background: url(/foo.jpg) }
|
34
|
+
CSS
|
35
|
+
|
36
|
+
output.should include('url(https://cdn.example.com/foo.jpg)')
|
37
|
+
end
|
38
|
+
|
39
|
+
it "rewrites URLs without SSL when configured without SSL" do
|
40
|
+
ActionController::Base.stub!(:asset_host => "http://cdn.example.com")
|
41
|
+
|
42
|
+
output = AssetTrip::UrlRewriter.new("http").rewrite <<-CSS
|
43
|
+
.foo { background: url(/foo.jpg) }
|
44
|
+
CSS
|
45
|
+
|
46
|
+
output.should include('url(http://cdn.example.com/foo.jpg)')
|
47
|
+
end
|
48
|
+
|
49
|
+
it "adds the protocol to the host when necessary" do
|
50
|
+
ActionController::Base.stub!(:asset_host => "cdn.example.com")
|
51
|
+
|
52
|
+
output = AssetTrip::UrlRewriter.new("http").rewrite <<-CSS
|
53
|
+
.foo { background: url(/foo.jpg) }
|
54
|
+
CSS
|
55
|
+
|
56
|
+
output.should include('url(http://cdn.example.com/foo.jpg)')
|
57
|
+
end
|
58
|
+
|
59
|
+
it "replaces %d with a number in the asset host" do
|
60
|
+
ActionController::Base.stub!(:asset_host => "http://cdn%d.example.com")
|
61
|
+
|
62
|
+
output = AssetTrip::UrlRewriter.new("http").rewrite <<-CSS
|
63
|
+
.foo { background: url(/foo.jpg) }
|
64
|
+
CSS
|
65
|
+
|
66
|
+
output.should include('url(http://cdn1.example.com/foo.jpg)')
|
67
|
+
end
|
68
|
+
|
69
|
+
it "doesn't modify background-image paths pointing to other servers" do
|
70
|
+
ActionController::Base.stub!(:asset_host => "http://cdn.example.com")
|
71
|
+
|
72
|
+
output = AssetTrip::UrlRewriter.new("http").rewrite <<-CSS
|
73
|
+
.foo { background: url(http://google.com/foo.jpg) }
|
74
|
+
CSS
|
75
|
+
|
76
|
+
output.should include('url(http://google.com/foo.jpg)')
|
77
|
+
end
|
78
|
+
|
79
|
+
it "disregards leading and trailing whitespace and quotes" do
|
80
|
+
ActionController::Base.stub!(:asset_host => "http://cdn.example.com")
|
81
|
+
|
82
|
+
output = AssetTrip::UrlRewriter.new("http").rewrite <<-CSS
|
83
|
+
.foo1 { background: url( '/foo1.jpg' ) }
|
84
|
+
.foo2 { background: url( "/foo2.jpg" ) }
|
85
|
+
CSS
|
86
|
+
|
87
|
+
output.should include('url(http://cdn.example.com/foo1.jpg)')
|
88
|
+
output.should include('url(http://cdn.example.com/foo2.jpg)')
|
89
|
+
end
|
90
|
+
|
91
|
+
it "doesn't modify paths for .htc files" do
|
92
|
+
ActionController::Base.stub!(:asset_host => "http://cdn.example.com")
|
93
|
+
|
94
|
+
output = AssetTrip::UrlRewriter.new("http").rewrite <<-CSS
|
95
|
+
.foo { background: url(/foo.htc) }
|
96
|
+
CSS
|
97
|
+
|
98
|
+
output.should include('url(/foo.htc)')
|
99
|
+
end
|
100
|
+
|
101
|
+
it "works with asset host procs taking one arg" do
|
102
|
+
ActionController::Base.stub!(:asset_host => Proc.new { |source|
|
103
|
+
source.should_not be_nil
|
104
|
+
"http://cdn.example.com"
|
105
|
+
})
|
106
|
+
|
107
|
+
output = AssetTrip::UrlRewriter.new("http").rewrite <<-CSS
|
108
|
+
.foo { background: url(/foo.jpg) }
|
109
|
+
CSS
|
110
|
+
|
111
|
+
output.should include('url(http://cdn.example.com/foo.jpg)')
|
112
|
+
end
|
113
|
+
|
114
|
+
it "works with asset host procs taking two args" do
|
115
|
+
ActionController::Base.stub!(:asset_host => Proc.new { |source, request|
|
116
|
+
source.should_not be_nil
|
117
|
+
request.should_not be_nil
|
118
|
+
"http://cdn.example.com"
|
119
|
+
})
|
120
|
+
|
121
|
+
output = AssetTrip::UrlRewriter.new("http").rewrite <<-CSS
|
122
|
+
.foo { background: url(/foo.jpg) }
|
123
|
+
CSS
|
124
|
+
|
125
|
+
output.should include('url(http://cdn.example.com/foo.jpg)')
|
126
|
+
end
|
127
|
+
|
128
|
+
it "works with no asset host" do
|
129
|
+
ActionController::Base.stub!(:asset_host => nil)
|
130
|
+
|
131
|
+
output = AssetTrip::UrlRewriter.new("http").rewrite <<-CSS
|
132
|
+
.foo { background: url(/foo.jpg) }
|
133
|
+
CSS
|
134
|
+
|
135
|
+
output.should include('url(/foo.jpg)')
|
136
|
+
end
|
137
|
+
|
138
|
+
it "includes the file mtime for background images in the query string" do
|
139
|
+
rewriter = AssetTrip::UrlRewriter.new("http")
|
140
|
+
rewriter.stub!(:rails_asset_id => "123123123")
|
141
|
+
|
142
|
+
output = rewriter.rewrite <<-CSS
|
143
|
+
.foo { background: url(/foo.jpg) }
|
144
|
+
CSS
|
145
|
+
output.should include('url(/foo.jpg?123123123)')
|
146
|
+
end
|
147
|
+
|
148
|
+
it_rewrites_urls("/stylesheets/active_scaffold/default/stylesheet.css",
|
149
|
+
"../../../images/./../images/goober/../spinner.gif" => "/images/spinner.gif")
|
150
|
+
|
151
|
+
it_rewrites_urls("/stylesheets/active_scaffold/default/stylesheet.css",
|
152
|
+
"../../../images/spinner.gif" => "/images/spinner.gif")
|
153
|
+
|
154
|
+
it_rewrites_urls("/stylesheets/active_scaffold/default/./stylesheet.css",
|
155
|
+
"../../../images/spinner.gif" => "/images/spinner.gif")
|
156
|
+
|
157
|
+
it_rewrites_urls("/stylesheets/main.css",
|
158
|
+
"image.gif" => "/stylesheets/image.gif")
|
159
|
+
|
160
|
+
it_rewrites_urls("/stylesheets////default/main.css",
|
161
|
+
"..//image.gif" => "/stylesheets/image.gif")
|
162
|
+
|
163
|
+
it_rewrites_urls("/stylesheets/default/main.css",
|
164
|
+
"/images/image.gif" => "/images/image.gif")
|
165
|
+
end
|
166
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe AssetTrip do
|
4
|
+
describe "#manifest" do
|
5
|
+
context "when there is no manifest" do
|
6
|
+
it "raises a NoManifestError" do
|
7
|
+
lambda {
|
8
|
+
AssetTrip.manifest
|
9
|
+
}.should raise_error(AssetTrip::NoManifestError)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
alert("main/new")
|
@@ -0,0 +1 @@
|
|
1
|
+
alert("main");
|
@@ -0,0 +1 @@
|
|
1
|
+
alert("signup");
|
File without changes
|
File without changes
|