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.
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