asset-trip 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. data/.gitignore +2 -0
  2. data/History.txt +6 -0
  3. data/MIT-LICENSE.txt +19 -0
  4. data/README.rdoc +27 -0
  5. data/Rakefile +12 -0
  6. data/Thorfile +110 -0
  7. data/asset-trip.gemspec +107 -0
  8. data/init.rb +3 -0
  9. data/lib/asset_trip/asset.rb +82 -0
  10. data/lib/asset_trip/compressor.rb +36 -0
  11. data/lib/asset_trip/config.rb +60 -0
  12. data/lib/asset_trip/file_writer.rb +17 -0
  13. data/lib/asset_trip/helper.rb +83 -0
  14. data/lib/asset_trip/javascript.rb +29 -0
  15. data/lib/asset_trip/load_path.rb +39 -0
  16. data/lib/asset_trip/manifest.rb +40 -0
  17. data/lib/asset_trip/manifest_writer.rb +35 -0
  18. data/lib/asset_trip/memoizable.rb +28 -0
  19. data/lib/asset_trip/middleware.rb +109 -0
  20. data/lib/asset_trip/ssl_stylesheet.rb +15 -0
  21. data/lib/asset_trip/stylesheet.rb +44 -0
  22. data/lib/asset_trip/url_rewriter.rb +82 -0
  23. data/lib/asset_trip.rb +66 -0
  24. data/spec/asset_trip/asset_spec.rb +47 -0
  25. data/spec/asset_trip/compressor_spec.rb +46 -0
  26. data/spec/asset_trip/config_spec.rb +61 -0
  27. data/spec/asset_trip/helper_spec.rb +221 -0
  28. data/spec/asset_trip/javascript_spec.rb +24 -0
  29. data/spec/asset_trip/load_path_spec.rb +61 -0
  30. data/spec/asset_trip/manifest_writer_spec.rb +32 -0
  31. data/spec/asset_trip/middleware_spec.rb +72 -0
  32. data/spec/asset_trip/stylesheet_spec.rb +51 -0
  33. data/spec/asset_trip/url_rewriter_spec.rb +166 -0
  34. data/spec/asset_trip_spec.rb +13 -0
  35. data/spec/fixtures/app/javascripts/main/new.js +1 -0
  36. data/spec/fixtures/app/javascripts/main.js +1 -0
  37. data/spec/fixtures/app/javascripts/signup.js +1 -0
  38. data/spec/fixtures/app/stylesheets/new.css +0 -0
  39. data/spec/fixtures/config/asset_trip/assets.rb +0 -0
  40. data/spec/integration/bundle_spec.rb +243 -0
  41. data/spec/integration/prune_spec.rb +53 -0
  42. data/spec/spec.opts +3 -0
  43. data/spec/spec_helper.rb +24 -0
  44. data/spec/support/core_extensions.rb +13 -0
  45. data/spec/support/helpers.rb +33 -0
  46. data/spec/support/matchers.rb +67 -0
  47. data/spec/support/path_utils.rb +45 -0
  48. data/spec/support/sandbox_helper.rb +19 -0
  49. data/tasks/asset_trip.rake +11 -0
  50. data/vendor/yuicompressor-2.4.2.jar +0 -0
  51. 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