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,243 @@
1
+ require "spec_helper"
2
+ require "action_controller"
3
+
4
+ describe "rake asset_trip:bundle" do
5
+ setup_sandbox_app!(:each)
6
+
7
+ context "(disabling the YUI Compressor for speed)" do
8
+ before do
9
+ AssetTrip::Compressor.stub!(:new => DummyCompressor.new)
10
+ end
11
+
12
+ it "stores each Asset into the public directory" do
13
+ install_config <<-CONFIG
14
+ js_asset "signup" do
15
+ end
16
+ CONFIG
17
+ AssetTrip.bundle!
18
+ fixture_app.should have_asset("signup.js")
19
+ end
20
+
21
+ it "supports loading additional config files" do
22
+ install_config(<<-CONFIG, "assets.rb")
23
+ load "config/asset_trip/more_assets"
24
+ CONFIG
25
+ install_config(<<-CONFIG, "more_assets.rb")
26
+ js_asset "signup" do
27
+ end
28
+ CONFIG
29
+ AssetTrip.bundle!
30
+ fixture_app.should have_asset("signup.js")
31
+ end
32
+
33
+ it "concatenates the files into an Asset" do
34
+ install_config <<-CONFIG
35
+ js_asset "signup" do
36
+ include "main"
37
+ include "signup"
38
+ end
39
+ CONFIG
40
+ AssetTrip.bundle!
41
+ asset("signup.js").should have_contents('alert("main")')
42
+ asset("signup.js").should have_contents('alert("signup")')
43
+ end
44
+
45
+ it "uses the same path if the Asset content is the same" do
46
+ install_config <<-CONFIG
47
+ js_asset "signup" do
48
+ include "main.js"
49
+ end
50
+ CONFIG
51
+ AssetTrip.bundle!
52
+ AssetTrip.bundle!
53
+ assets("signup.js").should have(1).item
54
+ end
55
+
56
+ it "uses a different path if the Asset content is different" do
57
+ install_config <<-CONFIG
58
+ js_asset "signup" do
59
+ include "main.js"
60
+ end
61
+ CONFIG
62
+ AssetTrip.bundle!
63
+ AssetTrip.instance_variable_set(:@config, nil)
64
+ write_javascript("main.js", 'alert("new.main");')
65
+ AssetTrip.bundle!
66
+ assets("signup.js").should have(2).items
67
+ end
68
+
69
+ it "generates paths in the form of assets/XX/YYYYYYYY/filename.js" do
70
+ install_config <<-CONFIG
71
+ js_asset "signup" do
72
+ include "main.js"
73
+ end
74
+ CONFIG
75
+ AssetTrip.bundle!
76
+
77
+ directory = assets_path.glob("*").map { |f| File.basename(f) }.first
78
+ directory.size.should == 2
79
+ end
80
+
81
+ it "generates a manifest for use at runtime" do
82
+ install_config <<-CONFIG
83
+ js_asset "signup" do
84
+ include "main.js"
85
+ end
86
+ CONFIG
87
+ AssetTrip.bundle!
88
+
89
+ File.read(fixture_app.join("config", "asset_trip", "manifest.rb")).should be_like(<<-RUBY)
90
+ module AssetTrip
91
+ @manifest = Manifest.new
92
+ @manifest["signup.js"] = "7d6db1efb9e"
93
+ end
94
+ RUBY
95
+ end
96
+
97
+ it "rewrites URLs in CSS files to include the asset host" do
98
+ ActionController::Base.stub!(:asset_host => "http://cdn%d.example.com")
99
+
100
+ install_config <<-CONFIG
101
+ css_asset "signup" do
102
+ include "new"
103
+ end
104
+ CONFIG
105
+
106
+ write_stylesheet("new.css", <<-STYLESHEET)
107
+ .foo { background: url(/foo.jpg) }
108
+ STYLESHEET
109
+ AssetTrip.bundle!
110
+
111
+ asset("signup.css").should have_contents('url(http://cdn1.example.com/foo.jpg)')
112
+ end
113
+
114
+ it "rewrites URLs in CSS files to include HTTPs asset hosts" do
115
+ ActionController::Base.stub!(:asset_host => "http://cdn%d.example.com")
116
+
117
+ install_config <<-CONFIG
118
+ css_asset "signup" do
119
+ include "new"
120
+ end
121
+ CONFIG
122
+
123
+ write_stylesheet("new.css", <<-STYLESHEET)
124
+ .foo { background: url(/foo.jpg) }
125
+ STYLESHEET
126
+ AssetTrip.bundle!
127
+
128
+ asset("signup.ssl.css").should have_contents('url(https://cdn1.example.com/foo.jpg)')
129
+ end
130
+
131
+ it "respects ssl? method of request in asset proc" do
132
+ asset_proc = Proc.new { |source, request|
133
+ if request.ssl?
134
+ "https://assets.example.com"
135
+ else
136
+ "https://cdn.example.com"
137
+ end
138
+ }
139
+ ActionController::Base.stub!(:asset_host => asset_proc)
140
+ install_config <<-CONFIG
141
+ css_asset "signup" do
142
+ include "new"
143
+ end
144
+ CONFIG
145
+
146
+ write_stylesheet("new.css", <<-STYLESHEET)
147
+ .foo { background: url(/foo.jpg) }
148
+ STYLESHEET
149
+ AssetTrip.bundle!
150
+
151
+ asset("signup.ssl.css").should have_contents('url(https://assets.example.com/foo.jpg)')
152
+ end
153
+
154
+ it "does not write a new bundle if the package has not expired" do
155
+ install_config <<-CONFIG
156
+ js_asset "signup" do
157
+ include "main.js"
158
+ end
159
+ CONFIG
160
+ AssetTrip.bundle!
161
+
162
+ asset_mtime = 5.minutes.ago
163
+ source_mtime = 10.minutes.ago
164
+ asset("signup.js").utime(asset_mtime, asset_mtime)
165
+ app_javascript("main.js").utime(source_mtime, source_mtime)
166
+
167
+ AssetTrip.bundle!
168
+ asset("signup.js").mtime.to_i.should == asset_mtime.to_i
169
+ end
170
+
171
+ it "should use the most recent package to detect mtimes for expiry" do
172
+ install_config <<-CONFIG
173
+ js_asset "signup" do
174
+ include "main.js"
175
+ end
176
+ CONFIG
177
+ AssetTrip.bundle!
178
+
179
+ asset_mtime = 5.minutes.ago
180
+ source_mtime = 10.minutes.ago
181
+ oldest_asset_mtime = 15.minutes.ago
182
+
183
+ asset("signup.js").utime(asset_mtime, asset_mtime)
184
+ app_javascript("main.js").utime(source_mtime, source_mtime)
185
+ create_asset("46/123431bdc/signup.js", :mtime => oldest_asset_mtime)
186
+
187
+ AssetTrip.bundle!
188
+ assets("signup.js").map { |asset| asset.mtime.to_i }.sort.should == [oldest_asset_mtime.to_i, asset_mtime.to_i]
189
+ end
190
+ end
191
+
192
+ it "minifies JavaScript using the YUI Compressor" do
193
+ install_config <<-CONFIG
194
+ js_asset "signup" do
195
+ include "main"
196
+ end
197
+ CONFIG
198
+
199
+ write_javascript("main.js", <<-JAVASCRIPT)
200
+ // Comment
201
+ function foo() {
202
+ var long_var_name = 1;
203
+ return long_var_name + 1;
204
+ }
205
+ JAVASCRIPT
206
+ AssetTrip.bundle!
207
+
208
+ asset("signup.js").should_not have_contents('Comment')
209
+ asset("signup.js").should have_contents('return a+1')
210
+ end
211
+
212
+ it "minifies CSS using the YUI Compressor" do
213
+ install_config <<-CONFIG
214
+ css_asset "signup" do
215
+ include "new"
216
+ end
217
+ CONFIG
218
+
219
+ write_stylesheet("new.css", <<-STYLESHEET)
220
+ /* Comment */
221
+ .foo {
222
+ font-weight: bold;
223
+ }
224
+ STYLESHEET
225
+ AssetTrip.bundle!
226
+
227
+ asset("signup.css").should_not have_contents('Comment')
228
+ asset("signup.css").should have_contents('.foo{font-weight:bold;}')
229
+ end
230
+
231
+ it "raises a CompressorError if compression fails" do
232
+ install_config <<-CONFIG
233
+ js_asset "signup" do
234
+ include "main"
235
+ end
236
+ CONFIG
237
+ write_javascript("main.js", "!@$%&*")
238
+
239
+ lambda {
240
+ AssetTrip.bundle!
241
+ }.should raise_error(AssetTrip::CompressorError)
242
+ end
243
+ end
@@ -0,0 +1,53 @@
1
+ require "spec_helper"
2
+
3
+ describe "rake asset_trip:prune" do
4
+ setup_sandbox_app!(:each)
5
+
6
+ before do
7
+ AssetTrip::Compressor.stub!(:new => DummyCompressor.new)
8
+ end
9
+
10
+ it "removes assets not in the current Manifest" do
11
+ install_config <<-CONFIG
12
+ js_asset "signup" do
13
+ include "main.js"
14
+ end
15
+ CONFIG
16
+ AssetTrip.bundle!
17
+ AssetTrip.instance_variable_set(:@config, nil)
18
+ write_javascript("main.js", 'alert("new.main");')
19
+ AssetTrip.bundle!
20
+ load fixture_app.join("config", "asset_trip", "manifest.rb")
21
+ AssetTrip.prune!
22
+ assets("signup.js").should have(1).item
23
+ end
24
+
25
+ it "does not remove assets in the current Manifest" do
26
+ install_config <<-CONFIG
27
+ js_asset "signup" do
28
+ include "main.js"
29
+ end
30
+ CONFIG
31
+ AssetTrip.bundle!
32
+ load fixture_app.join("config", "asset_trip", "manifest.rb")
33
+ AssetTrip.prune!
34
+ assets("signup.js").should have(1).item
35
+ end
36
+
37
+ it "removes unknown files" do
38
+ install_config <<-CONFIG
39
+ js_asset "signup" do
40
+ include "main.js"
41
+ end
42
+ CONFIG
43
+ AssetTrip.bundle!
44
+
45
+ File.open(assets_path.join("blah.jpg"), "w") do |f|
46
+ f << "blah!"
47
+ end
48
+
49
+ load fixture_app.join("config", "asset_trip", "manifest.rb")
50
+ AssetTrip.prune!
51
+ assets("blah.jpg").should have(0).items
52
+ end
53
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ -fs
3
+ --debugger
@@ -0,0 +1,24 @@
1
+ require "asset_trip"
2
+
3
+ Dir[File.join(File.dirname(__FILE__), 'support', '*.rb')].each do |file|
4
+ require file
5
+ end
6
+
7
+ class DummyCompressor
8
+ def compress(contents)
9
+ return contents
10
+ end
11
+ end
12
+
13
+ Spec::Runner.configure do |config|
14
+ config.include AssetTrip::Spec::Helpers
15
+ config.include AssetTrip::Spec::Matchers
16
+ config.include AssetTrip::Spec::PathUtils
17
+ config.extend AssetTrip::Spec::SandboxHelper
18
+
19
+ config.before do
20
+ # TODO: Is there a better way to accomodate this concern?
21
+ AssetTrip.instance_variable_set(:@config, nil)
22
+ AssetTrip.instance_variable_set(:@manifest, nil)
23
+ end
24
+ end
@@ -0,0 +1,13 @@
1
+ require "pathname"
2
+
3
+ module AssetTrip
4
+ module Spec
5
+ module PathnameExtensions
6
+ def glob(*args)
7
+ self.class.glob(self.join(*args))
8
+ end
9
+ end
10
+
11
+ Pathname.send(:include, PathnameExtensions)
12
+ end
13
+ end
@@ -0,0 +1,33 @@
1
+ module AssetTrip
2
+ module Spec
3
+ module Helpers
4
+
5
+ def install_config(config_source, filename = "assets.rb")
6
+ FileUtils.mkdir_p(fixture_app)
7
+ File.open(fixture_app("config", "asset_trip", filename), 'w') do |f|
8
+ f.puts config_source
9
+ end
10
+ end
11
+
12
+ def write_javascript(name, contents)
13
+ File.open(app_javascript(name), "w") do |f|
14
+ f.puts contents
15
+ end
16
+ end
17
+
18
+ def write_stylesheet(name, contents)
19
+ File.open(app_stylesheet(name), "w") do |f|
20
+ f.puts contents
21
+ end
22
+ end
23
+
24
+ def create_asset(path, opts = {})
25
+ fake_asset = assets_path.join(path)
26
+ FileUtils.mkdir_p(fake_asset.dirname)
27
+ FileUtils.touch(fake_asset)
28
+ fake_asset.utime(opts[:mtime], opts[:mtime]) if opts[:mtime]
29
+ end
30
+
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,67 @@
1
+ module AssetTrip
2
+ module Spec
3
+ module Matchers
4
+
5
+ class BeLike
6
+ def initialize(expected)
7
+ @expected = expected
8
+ end
9
+
10
+ def matches?(actual)
11
+ @actual = actual
12
+ @expected.gsub(/\s+/, ' ').strip == @actual.gsub(/\s+/, ' ').strip
13
+ end
14
+
15
+ def failure_message
16
+ "expected\n#{@actual}\nto be like\n#{@expected}"
17
+ end
18
+
19
+ def negative_failure_message
20
+ "expected\n#{@actual}\nto be unlike\n#{@expected}"
21
+ end
22
+ end
23
+
24
+ def be_like(expected)
25
+ BeLike.new(expected)
26
+ end
27
+
28
+ def have_asset(name)
29
+ simple_matcher("have asset") do |path|
30
+ File.exist?(assets_path.glob("**", name).first)
31
+ end
32
+ end
33
+
34
+ def have_directory(name)
35
+ simple_matcher("have directory") do |path|
36
+ matches = path.glob("**", name)
37
+ matches.any? { |path| File.directory?(path) }
38
+ end
39
+ end
40
+
41
+ class HaveContents
42
+ def initialize(text)
43
+ @text = text
44
+ end
45
+
46
+ def matches?(path)
47
+ @path = path
48
+ @actual = File.read(path)
49
+ @actual.include?(@text)
50
+ end
51
+
52
+ def failure_message
53
+ "expected #{@path}\n#{@actual}\nto include\n#{@text}"
54
+ end
55
+
56
+ def negative_failure_message
57
+ "expected #{@path}\n#{@actual}\nto not include\n#{@text}"
58
+ end
59
+ end
60
+
61
+ def have_contents(text)
62
+ HaveContents.new(text)
63
+ end
64
+
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,45 @@
1
+ module AssetTrip
2
+ module Spec
3
+ module PathUtils
4
+
5
+ def reset_filesystem!
6
+ tmp_path.rmtree if tmp_path.exist?
7
+ tmp_path.mkdir
8
+ FileUtils.cp_r(root.join("spec", "fixtures"), fixture_app)
9
+ end
10
+
11
+ def root
12
+ Pathname.new(__FILE__).dirname.join('..', '..').expand_path
13
+ end
14
+
15
+ def tmp_path
16
+ root.join("tmp")
17
+ end
18
+
19
+ def fixture_app(*args)
20
+ tmp_path.join("fixture_app", *args)
21
+ end
22
+
23
+ def app_javascript(*args)
24
+ fixture_app.join("app", "javascripts", *args)
25
+ end
26
+
27
+ def app_stylesheet(*args)
28
+ fixture_app.join("app", "stylesheets", *args)
29
+ end
30
+
31
+ def asset(name)
32
+ assets(name).first
33
+ end
34
+
35
+ def assets(name)
36
+ assets_path.glob("**", name)
37
+ end
38
+
39
+ def assets_path
40
+ fixture_app.join("public", "assets")
41
+ end
42
+
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,19 @@
1
+ module AssetTrip
2
+ module Spec
3
+ module SandboxHelper
4
+
5
+ def setup_sandbox_app!(around = :all)
6
+ before(around) do
7
+ reset_filesystem!
8
+ @old_pwd = Dir.pwd
9
+ Dir.chdir(fixture_app)
10
+ end
11
+
12
+ after(around) do
13
+ Dir.chdir(@old_pwd)
14
+ end
15
+ end
16
+
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,11 @@
1
+ namespace :assets do
2
+ desc "Bundle assets"
3
+ task :bundle => :environment do
4
+ AssetTrip.bundle!
5
+ end
6
+
7
+ desc "Prune assets"
8
+ task :prune => :environment do
9
+ AssetTrip.prune!
10
+ end
11
+ end
Binary file
metadata ADDED
@@ -0,0 +1,128 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: asset-trip
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Bryan Helmkamp
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-11-05 00:00:00 -05:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: |-
17
+ Asset Trip bundles JavaScript and CSS files at deploy time. The assets are
18
+ then served from a Git-esque object store in the application's public
19
+ directory.
20
+ email: bryan@brynary.com
21
+ executables: []
22
+
23
+ extensions: []
24
+
25
+ extra_rdoc_files:
26
+ - History.txt
27
+ - README.rdoc
28
+ - MIT-LICENSE.txt
29
+ files:
30
+ - .gitignore
31
+ - History.txt
32
+ - MIT-LICENSE.txt
33
+ - README.rdoc
34
+ - Rakefile
35
+ - Thorfile
36
+ - asset-trip.gemspec
37
+ - init.rb
38
+ - lib/asset_trip.rb
39
+ - lib/asset_trip/asset.rb
40
+ - lib/asset_trip/compressor.rb
41
+ - lib/asset_trip/config.rb
42
+ - lib/asset_trip/file_writer.rb
43
+ - lib/asset_trip/helper.rb
44
+ - lib/asset_trip/javascript.rb
45
+ - lib/asset_trip/load_path.rb
46
+ - lib/asset_trip/manifest.rb
47
+ - lib/asset_trip/manifest_writer.rb
48
+ - lib/asset_trip/memoizable.rb
49
+ - lib/asset_trip/middleware.rb
50
+ - lib/asset_trip/ssl_stylesheet.rb
51
+ - lib/asset_trip/stylesheet.rb
52
+ - lib/asset_trip/url_rewriter.rb
53
+ - spec/asset_trip/asset_spec.rb
54
+ - spec/asset_trip/compressor_spec.rb
55
+ - spec/asset_trip/config_spec.rb
56
+ - spec/asset_trip/helper_spec.rb
57
+ - spec/asset_trip/javascript_spec.rb
58
+ - spec/asset_trip/load_path_spec.rb
59
+ - spec/asset_trip/manifest_writer_spec.rb
60
+ - spec/asset_trip/middleware_spec.rb
61
+ - spec/asset_trip/stylesheet_spec.rb
62
+ - spec/asset_trip/url_rewriter_spec.rb
63
+ - spec/asset_trip_spec.rb
64
+ - spec/fixtures/app/javascripts/main.js
65
+ - spec/fixtures/app/javascripts/main/new.js
66
+ - spec/fixtures/app/javascripts/signup.js
67
+ - spec/fixtures/app/stylesheets/new.css
68
+ - spec/fixtures/config/asset_trip/assets.rb
69
+ - spec/integration/bundle_spec.rb
70
+ - spec/integration/prune_spec.rb
71
+ - spec/spec.opts
72
+ - spec/spec_helper.rb
73
+ - spec/support/core_extensions.rb
74
+ - spec/support/helpers.rb
75
+ - spec/support/matchers.rb
76
+ - spec/support/path_utils.rb
77
+ - spec/support/sandbox_helper.rb
78
+ - tasks/asset_trip.rake
79
+ - vendor/yuicompressor-2.4.2.jar
80
+ has_rdoc: true
81
+ homepage: http://github.com/brynary/asset-trip
82
+ licenses: []
83
+
84
+ post_install_message:
85
+ rdoc_options: []
86
+
87
+ require_paths:
88
+ - lib
89
+ required_ruby_version: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ version: "0"
94
+ version:
95
+ required_rubygems_version: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ version: "0"
100
+ version:
101
+ requirements: []
102
+
103
+ rubyforge_project:
104
+ rubygems_version: 1.3.5
105
+ signing_key:
106
+ specification_version: 3
107
+ summary: Rails asset bundling plugin that will expand your mind
108
+ test_files:
109
+ - spec/asset_trip/asset_spec.rb
110
+ - spec/asset_trip/compressor_spec.rb
111
+ - spec/asset_trip/config_spec.rb
112
+ - spec/asset_trip/helper_spec.rb
113
+ - spec/asset_trip/javascript_spec.rb
114
+ - spec/asset_trip/load_path_spec.rb
115
+ - spec/asset_trip/manifest_writer_spec.rb
116
+ - spec/asset_trip/middleware_spec.rb
117
+ - spec/asset_trip/stylesheet_spec.rb
118
+ - spec/asset_trip/url_rewriter_spec.rb
119
+ - spec/asset_trip_spec.rb
120
+ - spec/fixtures/config/asset_trip/assets.rb
121
+ - spec/integration/bundle_spec.rb
122
+ - spec/integration/prune_spec.rb
123
+ - spec/spec_helper.rb
124
+ - spec/support/core_extensions.rb
125
+ - spec/support/helpers.rb
126
+ - spec/support/matchers.rb
127
+ - spec/support/path_utils.rb
128
+ - spec/support/sandbox_helper.rb