asset_hat 0.2.1 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/HISTORY +38 -19
- data/README.rdoc +99 -41
- data/Rakefile +17 -10
- data/VERSION.yml +3 -3
- data/app/helpers/asset_hat_helper.rb +40 -20
- data/asset_hat.gemspec +105 -101
- data/doc/classes/AssetHat.html +173 -59
- data/doc/classes/AssetHat/CSS.html +35 -26
- data/doc/classes/AssetHat/CSS/Engines.html +13 -12
- data/doc/classes/AssetHat/JS.html +11 -11
- data/doc/classes/AssetHat/JS/Engines.html +10 -10
- data/doc/classes/AssetHat/JS/Vendors.html +9 -5
- data/doc/classes/AssetHatHelper.html +18 -14
- data/doc/created.rid +1 -1
- data/doc/files/HISTORY.html +66 -24
- data/doc/files/LICENSE.html +1 -1
- data/doc/files/README_rdoc.html +112 -37
- data/doc/files/app/helpers/asset_hat_helper_rb.html +1 -1
- data/doc/files/lib/asset_hat/capistrano_rb.html +1 -1
- data/doc/files/lib/asset_hat/css_rb.html +1 -1
- data/doc/files/lib/asset_hat/js/vendors_rb.html +1 -1
- data/doc/files/lib/asset_hat/js_rb.html +1 -1
- data/doc/files/lib/asset_hat/tasks/css_rb.html +1 -1
- data/doc/files/lib/asset_hat/tasks/js_rb.html +1 -1
- data/doc/files/lib/asset_hat/tasks_rb.html +1 -1
- data/doc/files/lib/asset_hat/vcs_rb.html +1 -1
- data/doc/files/lib/asset_hat/version_rb.html +1 -1
- data/doc/files/lib/asset_hat_rb.html +1 -1
- data/doc/fr_method_index.html +54 -46
- data/lib/asset_hat.rb +100 -16
- data/lib/asset_hat/capistrano.rb +4 -3
- data/lib/asset_hat/css.rb +69 -20
- data/lib/asset_hat/js.rb +2 -2
- data/lib/asset_hat/js/vendors.rb +14 -10
- data/lib/asset_hat/tasks.rb +22 -3
- data/lib/asset_hat/tasks/css.rb +118 -74
- data/lib/asset_hat/tasks/js.rb +79 -35
- data/lib/asset_hat/vcs.rb +19 -0
- data/public/stylesheets/bundles/ssl/css-bundle-1.min.css +3 -0
- data/public/stylesheets/bundles/ssl/css-bundle-2.min.css +3 -0
- data/public/stylesheets/bundles/ssl/css-bundle-3.min.css +3 -0
- data/rails/init.rb +1 -16
- data/test/asset_hat_helper_test.rb +172 -28
- data/test/asset_hat_test.rb +167 -25
- metadata +54 -21
- data/.gitignore +0 -2
data/lib/asset_hat/vcs.rb
CHANGED
@@ -69,4 +69,23 @@ module AssetHat
|
|
69
69
|
@last_commit_ids
|
70
70
|
end
|
71
71
|
|
72
|
+
# Precomputes and caches the last commit ID for all bundles. Your web server
|
73
|
+
# process(es) should run this at boot to avoid overhead during user runtime.
|
74
|
+
def self.cache_last_commit_ids
|
75
|
+
AssetHat::TYPES.each do |type|
|
76
|
+
next if AssetHat.config[type.to_s].blank? ||
|
77
|
+
AssetHat.config[type.to_s]['bundles'].blank?
|
78
|
+
|
79
|
+
AssetHat.config[type.to_s]['bundles'].keys.each do |bundle|
|
80
|
+
# Memoize commit ID for this bundle
|
81
|
+
AssetHat.last_bundle_commit_id(bundle, type) if AssetHat.cache?
|
82
|
+
|
83
|
+
# Memoize commit IDs for each file in this bundle
|
84
|
+
AssetHat.bundle_filepaths(bundle, type).each do |filepath|
|
85
|
+
AssetHat.last_commit_id(filepath)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
72
91
|
end
|
data/rails/init.rb
CHANGED
@@ -1,17 +1,2 @@
|
|
1
1
|
::ActionView::Base.send(:include, AssetHatHelper)
|
2
|
-
|
3
|
-
# Precalculate (and memoize) asset commit IDs
|
4
|
-
AssetHat::TYPES.each do |type|
|
5
|
-
next if AssetHat.config[type.to_s].blank? ||
|
6
|
-
AssetHat.config[type.to_s]['bundles'].blank?
|
7
|
-
|
8
|
-
AssetHat.config[type.to_s]['bundles'].keys.each do |bundle|
|
9
|
-
# Memoize commit ID for this bundle
|
10
|
-
AssetHat.last_bundle_commit_id(bundle, type) if AssetHat.cache?
|
11
|
-
|
12
|
-
# Memoize commit IDs for each file in this bundle
|
13
|
-
AssetHat.bundle_filepaths(bundle, type).each do |filepath|
|
14
|
-
AssetHat.last_commit_id(filepath)
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
2
|
+
AssetHat.cache_last_commit_ids unless defined?(::IRB)
|
@@ -8,11 +8,12 @@ class AssetHatHelperTest < ActionView::TestCase
|
|
8
8
|
context 'with minified versions' do
|
9
9
|
setup do
|
10
10
|
@commit_id = '111'
|
11
|
-
flexmock(AssetHat
|
11
|
+
flexmock(AssetHat, :last_commit_id => @commit_id)
|
12
12
|
end
|
13
13
|
|
14
|
-
should 'include one file by name, and
|
15
|
-
|
14
|
+
should 'include one file by name, and ' +
|
15
|
+
'automatically use minified version' do
|
16
|
+
flexmock(AssetHat, :asset_exists? => true)
|
16
17
|
output = include_css('foo', :cache => true)
|
17
18
|
assert_equal css_tag("foo.min.css?#{@commit_id}"), output
|
18
19
|
end
|
@@ -28,7 +29,7 @@ class AssetHatHelperTest < ActionView::TestCase
|
|
28
29
|
end
|
29
30
|
|
30
31
|
should 'include multiple files by name' do
|
31
|
-
flexmock(AssetHat
|
32
|
+
flexmock(AssetHat, :asset_exists? => true)
|
32
33
|
expected = %w[foo bar].map do |source|
|
33
34
|
css_tag("#{source}.min.css?#{@commit_id}")
|
34
35
|
end.join("\n")
|
@@ -39,12 +40,43 @@ class AssetHatHelperTest < ActionView::TestCase
|
|
39
40
|
should 'include multiple files as a bundle' do
|
40
41
|
bundle = 'css-bundle-1'
|
41
42
|
output = include_css(:bundle => bundle, :cache => true)
|
42
|
-
assert_equal
|
43
|
+
assert_equal(
|
44
|
+
css_tag("bundles/#{bundle}.min.css?#{@commit_id}"), output)
|
43
45
|
end
|
46
|
+
|
47
|
+
context 'via SSL' do
|
48
|
+
setup do
|
49
|
+
@request = ActionController::TestRequest.new
|
50
|
+
flexmock(@controller, :request => @request)
|
51
|
+
flexmock(@controller.request, :ssl? => true)
|
52
|
+
assert @controller.request.ssl?,
|
53
|
+
'Precondition: Request should use SSL'
|
54
|
+
end
|
55
|
+
|
56
|
+
should 'include multiple files as a SSL bundle' do
|
57
|
+
flexmock(AssetHat, :ssl_asset_host_differs? => true)
|
58
|
+
|
59
|
+
bundle = 'css-bundle-1'
|
60
|
+
output = include_css(:bundle => bundle, :cache => true)
|
61
|
+
assert_equal(
|
62
|
+
css_tag("bundles/ssl/#{bundle}.min.css?#{@commit_id}"), output)
|
63
|
+
end
|
64
|
+
|
65
|
+
should 'use non-SSL CSS if SSL/non-SSL asset hosts are the same' do
|
66
|
+
flexmock(AssetHat, :ssl_asset_host_differs? => false)
|
67
|
+
|
68
|
+
bundle = 'css-bundle-1'
|
69
|
+
output = include_css(:bundle => bundle, :cache => true)
|
70
|
+
assert_equal(
|
71
|
+
css_tag("bundles/#{bundle}.min.css?#{@commit_id}"), output)
|
72
|
+
end
|
73
|
+
end # context 'via SSL'
|
74
|
+
|
44
75
|
end # context 'with minified versions'
|
45
76
|
|
46
77
|
context 'without minified versions' do
|
47
|
-
should 'include one file by name, and
|
78
|
+
should 'include one file by name, and ' +
|
79
|
+
'automatically use original version' do
|
48
80
|
output = include_css('foo')
|
49
81
|
assert_equal css_tag('foo.css'), output
|
50
82
|
end
|
@@ -52,7 +84,8 @@ class AssetHatHelperTest < ActionView::TestCase
|
|
52
84
|
end # context 'with caching enabled'
|
53
85
|
|
54
86
|
context 'with caching disabled' do
|
55
|
-
should 'include one file by name, and
|
87
|
+
should 'include one file by name, and ' +
|
88
|
+
'automatically use original version' do
|
56
89
|
output = include_css('foo', :cache => false)
|
57
90
|
assert_equal css_tag('foo.css'), output
|
58
91
|
end
|
@@ -63,7 +96,8 @@ class AssetHatHelperTest < ActionView::TestCase
|
|
63
96
|
end
|
64
97
|
|
65
98
|
should 'include multiple files by name' do
|
66
|
-
expected = %w[foo bar.min].
|
99
|
+
expected = %w[foo bar.min].
|
100
|
+
map { |src| css_tag("#{src}.css") }.join("\n")
|
67
101
|
output = include_css('foo', 'bar.min', :cache => false)
|
68
102
|
assert_equal expected, output
|
69
103
|
end
|
@@ -98,20 +132,27 @@ class AssetHatHelperTest < ActionView::TestCase
|
|
98
132
|
end # context 'include_css'
|
99
133
|
|
100
134
|
context 'include_js' do
|
135
|
+
setup do
|
136
|
+
@request = ActionController::TestRequest.new
|
137
|
+
flexmock(@controller, :request => @request)
|
138
|
+
end
|
139
|
+
|
101
140
|
context 'with caching enabled' do
|
102
141
|
context 'with minified versions' do
|
103
142
|
setup do
|
104
143
|
@commit_id = '111'
|
105
|
-
flexmock(AssetHat
|
144
|
+
flexmock(AssetHat,
|
106
145
|
:last_commit_id => @commit_id,
|
107
146
|
:last_bundle_commit_id => @commit_id
|
108
147
|
)
|
109
148
|
end
|
110
149
|
|
111
|
-
should 'include one file by name, and
|
112
|
-
|
150
|
+
should 'include one file by name, and ' +
|
151
|
+
'automatically use minified version' do
|
152
|
+
flexmock(AssetHat, :asset_exists? => true)
|
113
153
|
output = include_js('jquery.some-plugin', :cache => true)
|
114
|
-
assert_equal js_tag("jquery.some-plugin.min.js?#{@commit_id}"),
|
154
|
+
assert_equal js_tag("jquery.some-plugin.min.js?#{@commit_id}"),
|
155
|
+
output
|
115
156
|
end
|
116
157
|
|
117
158
|
should 'include one unminified file by name and extension' do
|
@@ -121,7 +162,8 @@ class AssetHatHelperTest < ActionView::TestCase
|
|
121
162
|
|
122
163
|
should 'include one minified file by name and extension' do
|
123
164
|
output = include_js('jquery.some-plugin.min.js', :cache => true)
|
124
|
-
assert_equal
|
165
|
+
assert_equal(
|
166
|
+
js_tag("jquery.some-plugin.min.js?#{@commit_id}"), output)
|
125
167
|
end
|
126
168
|
|
127
169
|
context 'with vendors' do
|
@@ -132,10 +174,12 @@ class AssetHatHelperTest < ActionView::TestCase
|
|
132
174
|
end
|
133
175
|
|
134
176
|
should 'include jQuery and jQuery UI' do
|
135
|
-
flexmock(AssetHat
|
177
|
+
flexmock(AssetHat, :config => @original_config)
|
136
178
|
[:jquery, :jquery_ui].each do |vendor|
|
137
179
|
output = include_js(vendor, :cache => true)
|
138
|
-
assert_equal
|
180
|
+
assert_equal(
|
181
|
+
js_tag("#{vendor.to_s.dasherize}.min.js?#{@commit_id}"),
|
182
|
+
output)
|
139
183
|
end
|
140
184
|
end
|
141
185
|
|
@@ -146,6 +190,58 @@ class AssetHatHelperTest < ActionView::TestCase
|
|
146
190
|
# N.B.: Including only the regular, not minified, version
|
147
191
|
end
|
148
192
|
end
|
193
|
+
|
194
|
+
context 'with remote requests via SSL' do
|
195
|
+
should 'include vendor JS via Google CDN' do
|
196
|
+
AssetHat::JS::VENDORS.each do |vendor|
|
197
|
+
AssetHat.html_cache[:js] = {}
|
198
|
+
helper_opts = {:version => '1', :cache => true}
|
199
|
+
|
200
|
+
flexmock_teardown
|
201
|
+
flexmock(AssetHat, :cache? => true)
|
202
|
+
flexmock(ActionController::Base,
|
203
|
+
:consider_all_requests_local => false)
|
204
|
+
flexmock(@controller.request, :ssl? => true)
|
205
|
+
assert @controller.request.ssl?,
|
206
|
+
'Precondition: Request should use SSL'
|
207
|
+
|
208
|
+
https_html = include_js(vendor, helper_opts.dup)
|
209
|
+
assert_match(
|
210
|
+
%r{src="https://ajax\.googleapis\.com/}, https_html)
|
211
|
+
assert_equal 1, AssetHat.html_cache[:js].size
|
212
|
+
assert_equal https_html,
|
213
|
+
AssetHat.html_cache[:js].to_a.first[1],
|
214
|
+
'SSL HTML should be cached'
|
215
|
+
|
216
|
+
http_cache_key = AssetHat.html_cache[:js].to_a.first[0]
|
217
|
+
flexmock_teardown
|
218
|
+
flexmock(AssetHat, :cache? => true)
|
219
|
+
flexmock(ActionController::Base,
|
220
|
+
:consider_all_requests_local => false)
|
221
|
+
flexmock(@controller.request, :ssl? => false)
|
222
|
+
assert !@controller.request.ssl?,
|
223
|
+
'Precondition: Request should not use SSL'
|
224
|
+
assert_equal 1, AssetHat.html_cache[:js].size
|
225
|
+
assert_equal https_html,
|
226
|
+
AssetHat.html_cache[:js][http_cache_key],
|
227
|
+
'SSL HTML should be still be cached'
|
228
|
+
|
229
|
+
http_html = include_js(vendor, helper_opts)
|
230
|
+
assert_match(
|
231
|
+
%r{src="http://ajax\.googleapis\.com/},
|
232
|
+
http_html,
|
233
|
+
'Should not use same cached HTML for SSL and non-SSL')
|
234
|
+
assert_equal 2, AssetHat.html_cache[:js].size
|
235
|
+
assert_equal https_html,
|
236
|
+
AssetHat.html_cache[:js][http_cache_key],
|
237
|
+
'SSH HTML should still be cached'
|
238
|
+
assert_equal http_html,
|
239
|
+
AssetHat.html_cache[:js].except(http_cache_key).
|
240
|
+
to_a.first[1],
|
241
|
+
'Non-SSL HTML should be cached'
|
242
|
+
end
|
243
|
+
end
|
244
|
+
end # context 'with remote requests via SSL'
|
149
245
|
end # context 'with vendor JS'
|
150
246
|
|
151
247
|
should 'include jQuery by version via helper option' do
|
@@ -162,10 +258,11 @@ class AssetHatHelperTest < ActionView::TestCase
|
|
162
258
|
config['js']['vendors'] = {
|
163
259
|
'jquery' => {
|
164
260
|
'version' => version,
|
165
|
-
'remote_url' => 'http://example.com/cdn/jquery.min.js'
|
261
|
+
'remote_url' => 'http://example.com/cdn/jquery.min.js',
|
262
|
+
'remote_ssl_url' => 'https://secure.example.com/cdn/jquery.min.js'
|
166
263
|
}
|
167
264
|
}
|
168
|
-
flexmock(AssetHat
|
265
|
+
flexmock(AssetHat, :config => config)
|
169
266
|
end
|
170
267
|
|
171
268
|
should 'include jQuery by version via config file' do
|
@@ -178,14 +275,25 @@ class AssetHatHelperTest < ActionView::TestCase
|
|
178
275
|
|
179
276
|
context 'with remote requests' do
|
180
277
|
setup do
|
181
|
-
flexmock(ActionController::Base
|
278
|
+
flexmock(ActionController::Base,
|
182
279
|
:consider_all_requests_local => false)
|
183
280
|
end
|
184
281
|
|
185
282
|
should 'use specified remote URL for jQuery' do
|
186
283
|
src = AssetHat.config['js']['vendors']['jquery']['remote_url']
|
187
284
|
assert_equal(
|
188
|
-
%
|
285
|
+
%{<script src="#{src}" type="text/javascript"></script>},
|
286
|
+
include_js(:jquery, :cache => true)
|
287
|
+
)
|
288
|
+
end
|
289
|
+
|
290
|
+
should 'use specified remote SSL URL for jQuery' do
|
291
|
+
flexmock(@controller.request, :ssl? => true)
|
292
|
+
src =
|
293
|
+
AssetHat.config['js']['vendors']['jquery']['remote_ssl_url']
|
294
|
+
|
295
|
+
assert_equal(
|
296
|
+
%{<script src="#{src}" type="text/javascript"></script>},
|
189
297
|
include_js(:jquery, :cache => true)
|
190
298
|
)
|
191
299
|
end
|
@@ -193,7 +301,7 @@ class AssetHatHelperTest < ActionView::TestCase
|
|
193
301
|
end # context 'with a mock config'
|
194
302
|
|
195
303
|
should 'include multiple files by name' do
|
196
|
-
flexmock(AssetHat
|
304
|
+
flexmock(AssetHat, :asset_exists? => true)
|
197
305
|
expected = %w[foo jquery.bar].map do |source|
|
198
306
|
js_tag("#{source}.min.js?#{@commit_id}")
|
199
307
|
end.join("\n")
|
@@ -204,21 +312,51 @@ class AssetHatHelperTest < ActionView::TestCase
|
|
204
312
|
should 'include multiple files as a bundle' do
|
205
313
|
bundle = 'js-bundle-1'
|
206
314
|
output = include_js(:bundle => bundle, :cache => true)
|
207
|
-
assert_equal
|
315
|
+
assert_equal(
|
316
|
+
js_tag("bundles/#{bundle}.min.js?#{@commit_id}"), output)
|
208
317
|
end
|
209
318
|
|
210
319
|
should 'include multiple bundles' do
|
211
|
-
flexmock(AssetHat
|
320
|
+
flexmock(AssetHat, :asset_exists? => true)
|
212
321
|
expected = %w[foo bar].map do |bundle|
|
213
322
|
js_tag("bundles/#{bundle}.min.js?#{@commit_id}")
|
214
323
|
end.join("\n")
|
215
324
|
output = include_js(:bundles => %w[foo bar], :cache => true)
|
216
325
|
assert_equal expected, output
|
217
326
|
end
|
327
|
+
|
328
|
+
context 'via SSL' do
|
329
|
+
setup do
|
330
|
+
@request = ActionController::TestRequest.new
|
331
|
+
flexmock(@controller, :request => @request)
|
332
|
+
flexmock(@controller.request, :ssl? => true)
|
333
|
+
assert @controller.request.ssl?,
|
334
|
+
'Precondition: Request should use SSL'
|
335
|
+
end
|
336
|
+
|
337
|
+
should 'use non-SSL JS if SSL/non-SSL asset hosts differ' do
|
338
|
+
flexmock(AssetHat, :ssl_asset_host_differs? => true)
|
339
|
+
|
340
|
+
bundle = 'js-bundle-1'
|
341
|
+
output = include_js(:bundle => bundle, :cache => true)
|
342
|
+
assert_equal(
|
343
|
+
js_tag("bundles/#{bundle}.min.js?#{@commit_id}"), output)
|
344
|
+
end
|
345
|
+
|
346
|
+
should 'use non-SSL JS if SSL/non-SSL asset hosts are the same' do
|
347
|
+
flexmock(AssetHat, :ssl_asset_host_differs? => false)
|
348
|
+
|
349
|
+
bundle = 'js-bundle-1'
|
350
|
+
output = include_js(:bundle => bundle, :cache => true)
|
351
|
+
assert_equal(
|
352
|
+
js_tag("bundles/#{bundle}.min.js?#{@commit_id}"), output)
|
353
|
+
end
|
354
|
+
end # context 'via SSL'
|
218
355
|
end # context 'with minified versions'
|
219
356
|
|
220
357
|
context 'without minified versions' do
|
221
|
-
should 'include one file by name, and
|
358
|
+
should 'include one file by name, and ' +
|
359
|
+
'automatically use original version' do
|
222
360
|
output = include_js('jquery.some-plugin', :cache => true)
|
223
361
|
assert_equal js_tag('jquery.some-plugin.js'), output
|
224
362
|
end
|
@@ -226,7 +364,8 @@ class AssetHatHelperTest < ActionView::TestCase
|
|
226
364
|
end # context 'with caching enabled'
|
227
365
|
|
228
366
|
context 'with caching disabled' do
|
229
|
-
should 'include one file by name, and
|
367
|
+
should 'include one file by name, and ' +
|
368
|
+
'automatically use original version' do
|
230
369
|
output = include_js('foo', :cache => false)
|
231
370
|
assert_equal js_tag('foo.js'), output
|
232
371
|
end
|
@@ -242,7 +381,8 @@ class AssetHatHelperTest < ActionView::TestCase
|
|
242
381
|
end
|
243
382
|
|
244
383
|
should 'include multiple files by name' do
|
245
|
-
expected = %w[foo bar.min].
|
384
|
+
expected = %w[foo bar.min].
|
385
|
+
map { |src| js_tag("#{src}.js") }.join("\n")
|
246
386
|
output = include_js('foo', 'bar.min', :cache => false)
|
247
387
|
assert_equal expected, output
|
248
388
|
end
|
@@ -257,7 +397,8 @@ class AssetHatHelperTest < ActionView::TestCase
|
|
257
397
|
should 'include a bundle as separate files' do
|
258
398
|
bundle = 'js-bundle-1'
|
259
399
|
sources = @config['js']['bundles'][bundle]
|
260
|
-
expected = sources.
|
400
|
+
expected = sources.
|
401
|
+
map { |src| js_tag("#{src}.js?#{@asset_id}") }.join("\n")
|
261
402
|
output = include_js(:bundle => bundle, :cache => false)
|
262
403
|
assert_equal expected, output
|
263
404
|
end
|
@@ -281,11 +422,14 @@ class AssetHatHelperTest < ActionView::TestCase
|
|
281
422
|
private
|
282
423
|
|
283
424
|
def css_tag(filename)
|
284
|
-
%
|
425
|
+
%{
|
426
|
+
<link href="/stylesheets/#{filename}"
|
427
|
+
media="screen,projection" rel="stylesheet" type="text/css" />
|
428
|
+
}.strip.gsub(/\s+/, ' ')
|
285
429
|
end
|
286
430
|
|
287
431
|
def js_tag(filename)
|
288
|
-
%
|
432
|
+
%{<script src="/javascripts/#{filename}" type="text/javascript"></script>}
|
289
433
|
end
|
290
434
|
|
291
435
|
end
|
data/test/asset_hat_test.rb
CHANGED
@@ -2,9 +2,23 @@ require 'test_helper'
|
|
2
2
|
|
3
3
|
class AssetHatTest < ActiveSupport::TestCase
|
4
4
|
context 'AssetHat' do
|
5
|
+
should 'know where to store assets' do
|
6
|
+
assert_equal 'public/stylesheets', AssetHat.assets_dir(:css)
|
7
|
+
assert_equal 'public/javascripts', AssetHat.assets_dir(:js)
|
8
|
+
|
9
|
+
assert_equal 'bundles', AssetHat.bundles_dir
|
10
|
+
assert_equal 'bundles/ssl', AssetHat.bundles_dir(:ssl => true)
|
11
|
+
assert_equal 'public/stylesheets/bundles', AssetHat.bundles_dir(:css)
|
12
|
+
assert_equal 'public/javascripts/bundles', AssetHat.bundles_dir(:js)
|
13
|
+
assert_equal 'public/stylesheets/bundles/ssl',
|
14
|
+
AssetHat.bundles_dir(:css, :ssl => true)
|
15
|
+
assert_equal 'public/javascripts/bundles/ssl',
|
16
|
+
AssetHat.bundles_dir(:js, :ssl => true)
|
17
|
+
end
|
18
|
+
|
5
19
|
context 'with caching enabled' do
|
6
20
|
setup do
|
7
|
-
flexmock(AssetHat
|
21
|
+
flexmock(AssetHat, :cache? => true)
|
8
22
|
end
|
9
23
|
|
10
24
|
should 'memoize config' do
|
@@ -16,7 +30,7 @@ class AssetHatTest < ActiveSupport::TestCase
|
|
16
30
|
|
17
31
|
context 'with caching disabled' do
|
18
32
|
setup do
|
19
|
-
flexmock(AssetHat
|
33
|
+
flexmock(AssetHat, :cache? => false)
|
20
34
|
end
|
21
35
|
|
22
36
|
should 'not memoize config' do
|
@@ -25,6 +39,66 @@ class AssetHatTest < ActiveSupport::TestCase
|
|
25
39
|
3.times { AssetHat.config }
|
26
40
|
end
|
27
41
|
end # context 'with caching disabled'
|
42
|
+
|
43
|
+
should 'recognize existing assets' do
|
44
|
+
assert AssetHat.asset_exists?('css-file-1-1.css', :css)
|
45
|
+
assert !AssetHat.asset_exists?('non-existent-css', :css)
|
46
|
+
assert AssetHat.asset_exists?('js-file-1-1.js', :js)
|
47
|
+
assert !AssetHat.asset_exists?('non-existent-js', :js)
|
48
|
+
end
|
49
|
+
|
50
|
+
should "return a bundle's filenames" do
|
51
|
+
assert_equal %w[css-file-1-1 css-file-1-2 css-file-1-3],
|
52
|
+
AssetHat.bundle_filenames('css-bundle-1', :css)
|
53
|
+
end
|
54
|
+
|
55
|
+
should "return a bundle's filepaths" do
|
56
|
+
expected = [1,2,3].map { |i| "public/stylesheets/css-file-1-#{i}.css" }
|
57
|
+
assert_equal expected, AssetHat.bundle_filepaths('css-bundle-1', :css)
|
58
|
+
end
|
59
|
+
|
60
|
+
context 'with asset host' do
|
61
|
+
should 'compute asset host from a String' do
|
62
|
+
asset_host = 'http://cdn%d.example.com'
|
63
|
+
flexmock(ActionController::Base, :asset_host => asset_host)
|
64
|
+
assert_match /http:\/\/cdn\d\.example\.com/,
|
65
|
+
AssetHat.compute_asset_host(asset_host, 'x.png')
|
66
|
+
end
|
67
|
+
|
68
|
+
should 'compute asset host from a Proc' do
|
69
|
+
asset_host = Proc.new do |source, request|
|
70
|
+
if request.ssl?
|
71
|
+
"#{request.protocol}ssl.cdn#{source.hash % 4}.example.com"
|
72
|
+
else
|
73
|
+
"#{request.protocol}cdn#{source.hash % 4}.example.com"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
flexmock(ActionController::Base, :asset_host => asset_host)
|
77
|
+
|
78
|
+
assert_match /http:\/\/cdn\d\.example\.com/,
|
79
|
+
AssetHat.compute_asset_host(asset_host, 'x.png')
|
80
|
+
assert_match /https:\/\/ssl\.cdn\d\.example\.com/,
|
81
|
+
AssetHat.compute_asset_host(asset_host, 'x.png', :ssl => true)
|
82
|
+
end
|
83
|
+
|
84
|
+
should 'know that asset host is same between SSL and non-SSL URLs' do
|
85
|
+
asset_host = 'http://cdn%d.example.com'
|
86
|
+
flexmock(ActionController::Base, :asset_host => asset_host)
|
87
|
+
assert !AssetHat.ssl_asset_host_differs?
|
88
|
+
end
|
89
|
+
|
90
|
+
should 'know that asset host differs between SSL and non-SSL URLs' do
|
91
|
+
asset_host = Proc.new do |source, request|
|
92
|
+
if request.ssl?
|
93
|
+
"#{request.protocol}ssl.cdn#{source.hash % 4}.example.com"
|
94
|
+
else
|
95
|
+
"#{request.protocol}cdn#{source.hash % 4}.example.com"
|
96
|
+
end
|
97
|
+
end
|
98
|
+
flexmock(ActionController::Base, :asset_host => asset_host)
|
99
|
+
assert AssetHat.ssl_asset_host_differs?
|
100
|
+
end
|
101
|
+
end # context 'with asset host'
|
28
102
|
end # context 'AssetHat'
|
29
103
|
|
30
104
|
context 'AssetHat::CSS' do
|
@@ -35,31 +109,87 @@ class AssetHatTest < ActiveSupport::TestCase
|
|
35
109
|
|
36
110
|
should 'add image asset commit IDs' do
|
37
111
|
commit_id = 111
|
38
|
-
flexmock(AssetHat
|
39
|
-
flexmock(Rails
|
112
|
+
flexmock(AssetHat, :last_commit_id => commit_id)
|
113
|
+
flexmock(Rails, :public_path => '')
|
40
114
|
|
41
|
-
|
42
|
-
|
43
|
-
|
115
|
+
# No/single/double quotes:
|
116
|
+
['', "'", '"'].each do |quote|
|
117
|
+
img = '/images/foo.png'
|
118
|
+
assert_equal(
|
119
|
+
"p{background:url(#{quote}#{img}?#{commit_id}#{quote})}",
|
120
|
+
AssetHat::CSS.add_asset_commit_ids(
|
121
|
+
"p{background:url(#{quote}#{img}#{quote})}")
|
122
|
+
)
|
123
|
+
|
124
|
+
img = '/images/?id=foo.png'
|
125
|
+
assert_equal(
|
126
|
+
"p{background:url(#{quote}#{img}&#{commit_id}#{quote})}",
|
127
|
+
AssetHat::CSS.add_asset_commit_ids(
|
128
|
+
"p{background:url(#{quote}#{img}#{quote})}")
|
129
|
+
)
|
130
|
+
end
|
131
|
+
|
132
|
+
# Mismatched quotes (should remain untouched):
|
133
|
+
%w[
|
134
|
+
'/images/foo.png
|
135
|
+
'/images/?id=foo.png
|
136
|
+
/images/foo.png'
|
137
|
+
/images/?id=foo.png'
|
138
|
+
"/images/foo.png
|
139
|
+
"/images/?id=foo.png
|
140
|
+
/images/foo.png"
|
141
|
+
/images/?id=foo.png"
|
142
|
+
'/images/foo.png"
|
143
|
+
'/images/?id=foo.png"
|
144
|
+
"/images/foo.png'
|
145
|
+
"/images/?id=foo.png'
|
146
|
+
].each do |bad_url|
|
147
|
+
assert_equal "p{background:url(#{bad_url})}",
|
148
|
+
AssetHat::CSS.add_asset_commit_ids("p{background:url(#{bad_url})}")
|
149
|
+
end
|
44
150
|
end
|
45
151
|
|
46
152
|
should 'add .htc asset commit IDs' do
|
47
153
|
commit_id = 111
|
48
|
-
flexmock(AssetHat
|
49
|
-
flexmock(Rails
|
154
|
+
flexmock(AssetHat, :last_commit_id => commit_id)
|
155
|
+
flexmock(Rails, :public_path => '')
|
50
156
|
|
51
157
|
assert_equal "p{background:url(/htc/iepngfix.htc?#{commit_id})}",
|
52
158
|
AssetHat::CSS.add_asset_commit_ids(
|
53
|
-
|
159
|
+
"p{background:url(/htc/iepngfix.htc)}")
|
160
|
+
assert_equal "p{background:url(/htc/?id=iepngfix&#{commit_id})}",
|
161
|
+
AssetHat::CSS.add_asset_commit_ids(
|
162
|
+
"p{background:url(/htc/?id=iepngfix)}")
|
54
163
|
end
|
55
164
|
|
56
165
|
should 'add image asset hosts' do
|
57
|
-
asset_host
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
166
|
+
asset_host = 'http://cdn%d.example.com'
|
167
|
+
asset_host_regex = 'http://cdn\d\.example\.com'
|
168
|
+
|
169
|
+
# No/single/double quotes:
|
170
|
+
['', "'", '"'].each do |quote|
|
171
|
+
img = '/images/foo.png'
|
172
|
+
assert_match(
|
173
|
+
Regexp.new("^p\\{background:url\\(#{quote}" +
|
174
|
+
"#{asset_host_regex}#{Regexp.escape(img)}#{quote}\\)\\}$"),
|
175
|
+
AssetHat::CSS.add_asset_hosts(
|
176
|
+
"p{background:url(#{quote}#{img}#{quote})}", asset_host)
|
177
|
+
)
|
178
|
+
end
|
179
|
+
|
180
|
+
# Mismatched quotes (should remain untouched):
|
181
|
+
%w[
|
182
|
+
'/images/foo.png
|
183
|
+
/images/foo.png'
|
184
|
+
"/images/foo.png
|
185
|
+
/images/foo.png"
|
186
|
+
'/images/foo.png"
|
187
|
+
"/images/foo.png'
|
188
|
+
].each do |bad_url|
|
189
|
+
assert_equal "p{background:url(#{bad_url})}",
|
190
|
+
AssetHat::CSS.add_asset_hosts("p{background:url(#{bad_url})}",
|
191
|
+
asset_host)
|
192
|
+
end
|
63
193
|
end
|
64
194
|
|
65
195
|
should 'not add .htc asset hosts' do
|
@@ -70,6 +200,27 @@ class AssetHatTest < ActiveSupport::TestCase
|
|
70
200
|
'p{background:url(/htc/iepngfix.htc)}', asset_host)
|
71
201
|
)
|
72
202
|
end
|
203
|
+
|
204
|
+
context 'when minifying' do
|
205
|
+
setup do
|
206
|
+
@input = %{
|
207
|
+
.foo { width: 1px; }
|
208
|
+
.bar {}
|
209
|
+
.baz{ width : 2px; }
|
210
|
+
.qux {}
|
211
|
+
.quux { }
|
212
|
+
.corge {/* ! */}
|
213
|
+
}
|
214
|
+
end
|
215
|
+
|
216
|
+
context 'with cssmin engine' do
|
217
|
+
should 'remove rules that have empty declaration blocks' do
|
218
|
+
assert_equal '.foo{width:1px;}.baz{width:2px;}',
|
219
|
+
AssetHat::CSS.minify(@input, :engine => :cssmin)
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end # context 'when minifying'
|
223
|
+
|
73
224
|
end # context 'AssetHat::CSS'
|
74
225
|
|
75
226
|
context 'AssetHat::JS' do
|
@@ -79,13 +230,4 @@ class AssetHatTest < ActiveSupport::TestCase
|
|
79
230
|
end
|
80
231
|
end # context 'AssetHat::JS'
|
81
232
|
|
82
|
-
should "return a bundle's filenames" do
|
83
|
-
assert_equal %w[css-file-1-1 css-file-1-2 css-file-1-3],
|
84
|
-
AssetHat.bundle_filenames('css-bundle-1', :css)
|
85
|
-
end
|
86
|
-
|
87
|
-
should "return a bundle's filepaths" do
|
88
|
-
expected = [1,2,3].map { |i| "public/stylesheets/css-file-1-#{i}.css" }
|
89
|
-
assert_equal expected, AssetHat.bundle_filepaths('css-bundle-1', :css)
|
90
|
-
end
|
91
233
|
end
|