rack-zippy 1.2.1 → 2.0.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.
@@ -0,0 +1,14 @@
1
+ require_relative 'test_helper'
2
+
3
+ module Rack
4
+ module Zippy
5
+ class NullAssetCompilerTest < TestCase
6
+
7
+ def test_never_wants_to_compile_assets
8
+ asset_compiler = NullAssetCompiler.new
9
+ assert !asset_compiler.compiles?('/assets/application.css')
10
+ end
11
+
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,8 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head><title>Bar</title></head>
4
+ <body>
5
+ <h1>Bar</h1>
6
+ <p>Bar info goes here&hellip;</p>
7
+ </body>
8
+ </html>
@@ -0,0 +1,11 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head><title>Foo Welcomes You</title></head>
4
+ <body>
5
+ <h1>Foo Welcomes You!</h1>
6
+ <p>The Foo home page, for your enjoyment.</p>
7
+ <p>
8
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras nec lectus ut lectus elementum congue. Pellentesque id accumsan quam. Sed luctus fringilla est vehicula semper. Suspendisse egestas nulla at odio tristique, pellentesque commodo magna hendrerit. Praesent hendrerit velit eros, sit amet laoreet felis pellentesque eget. Duis eleifend semper mauris, at pellentesque ipsum lobortis quis. Nulla mollis tellus eu sem egestas, id porttitor arcu tincidunt. Sed elementum quam non felis consequat posuere ac ac lacus. Donec hendrerit dui at metus eleifend accumsan. Nunc eu porta arcu. Curabitur consectetur tellus eget vulputate placerat. Nam eget dignissim enim.
9
+ </p>
10
+ </body>
11
+ </html>
@@ -0,0 +1,8 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head><title>Welcome</title></head>
4
+ <body>
5
+ <h1>Welcome!</h1>
6
+ <p>This is the home page.</p>
7
+ </body>
8
+ </html>
@@ -1,3 +1,4 @@
1
+ <!doctype html>
1
2
  <html>
2
3
  <head><title>Hello and thanks</title></head>
3
4
  <body>
@@ -0,0 +1,46 @@
1
+ require_relative 'test_helper'
2
+
3
+ module Rack
4
+ module Zippy
5
+ class RailsAssetCompilerTest < TestCase
6
+
7
+ def setup
8
+ enter_rails_env
9
+ ::Rails.configuration.assets.compile = false
10
+ end
11
+
12
+ def test_rails_env_detected_if_rails_version_defined
13
+ assert ::Rails.version
14
+ assert RailsAssetCompiler.rails_env?
15
+ end
16
+
17
+ def test_not_rails_env
18
+ exit_rails_env
19
+ assert !RailsAssetCompiler.rails_env?
20
+ end
21
+
22
+ def test_wants_to_compile_assets_when_active
23
+ ::Rails.configuration.assets.compile = true
24
+ asset_compiler = RailsAssetCompiler.new
25
+ assert asset_compiler.send(:active?), 'should be active'
26
+ assert asset_compiler.compiles?('/assets/application.css')
27
+ end
28
+
29
+ def test_does_not_want_to_compile_anything_when_inactive
30
+ assert !::Rails.configuration.assets.compile, 'assets.compile should not be active'
31
+ asset_compiler = RailsAssetCompiler.new
32
+ assert !asset_compiler.send(:active?), 'should not be active'
33
+ assert !asset_compiler.compiles?('/assets/application.css')
34
+ assert !asset_compiler.compiles?('/thanks.html')
35
+ end
36
+
37
+ def test_does_not_want_to_compile_non_asset_when_active
38
+ ::Rails.configuration.assets.compile = true
39
+ asset_compiler = RailsAssetCompiler.new
40
+ assert asset_compiler.send(:active?), 'should be active'
41
+ assert !asset_compiler.compiles?('/thanks.html')
42
+ end
43
+
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,468 @@
1
+ require_relative 'test_helper'
2
+
3
+ module Rack
4
+ module Zippy
5
+ class ServeableFileTest < TestCase
6
+
7
+ CACHE_FRIENDLY_LAST_MODIFIED = 'Mon, 10 Jan 2005 10:00:00 GMT'
8
+
9
+ def setup
10
+ ensure_correct_working_directory
11
+ enter_rails_env
12
+ ::Rails.configuration.assets.compile = false
13
+ end
14
+
15
+ def teardown
16
+ revert_to_original_working_directory
17
+ end
18
+
19
+ def test_day_long_cache_headers_for_root_html_requests
20
+ serveable_file = ServeableFile.new(
21
+ :full_path_info => "/thanks.html",
22
+ :path => "#{asset_root}/thanks.html",
23
+ :has_encoding_variants => false,
24
+ :is_gzipped => false
25
+ )
26
+
27
+ cache_headers = serveable_file.cache_headers
28
+
29
+ assert_cache_max_age cache_headers, :day
30
+ assert_last_modified cache_headers, nil
31
+ end
32
+
33
+ def test_cache_max_age_is_month_for_root_favicon
34
+ serveable_file = ServeableFile.new(
35
+ :full_path_info => "/favicon.ico",
36
+ :path => "#{asset_root}/favicon.ico",
37
+ :has_encoding_variants => false,
38
+ :is_gzipped => false
39
+ )
40
+
41
+ assert_cache_max_age serveable_file.cache_headers, :month
42
+ end
43
+
44
+ def test_maximum_cache_headers_for_assets_subdir_requests
45
+ serveable_file = ServeableFile.new(
46
+ :full_path_info => "/assets/favicon.ico",
47
+ :path => "#{asset_root}/assets/favicon.ico",
48
+ :has_encoding_variants => false,
49
+ :is_gzipped => false
50
+ )
51
+
52
+ cache_headers = serveable_file.cache_headers
53
+
54
+ assert_cache_max_age cache_headers, :year
55
+ assert_cache_friendly_last_modified cache_headers
56
+ end
57
+
58
+ def test_cache_friendly_last_modified_is_not_set_for_files_outside_of_assets_subdir
59
+ serveable_file = ServeableFile.new(
60
+ :full_path_info => "/robots.txt",
61
+ :path => "#{asset_root}/robots.txt",
62
+ :has_encoding_variants => false,
63
+ :is_gzipped => false
64
+ )
65
+
66
+ assert_last_modified serveable_file.cache_headers, nil
67
+ end
68
+
69
+ def test_cache_friendly_last_modified_is_set_for_root_favicon_as_it_rarely_changes
70
+ serveable_file = ServeableFile.new(
71
+ :full_path_info => "/favicon.ico",
72
+ :path => "#{asset_root}/favicon.ico",
73
+ :has_encoding_variants => false,
74
+ :is_gzipped => false
75
+ )
76
+
77
+ assert_cache_friendly_last_modified serveable_file.cache_headers
78
+ end
79
+
80
+ def test_headers_sets_content_length
81
+ path = "#{asset_root}/thanks.html"
82
+
83
+ serveable_file = ServeableFile.new(
84
+ :full_path_info => "/thanks.html",
85
+ :path => path,
86
+ :has_encoding_variants => false,
87
+ :is_gzipped => false
88
+ )
89
+
90
+ headers = serveable_file.headers
91
+
92
+ file_size_in_bytes = ::File.size(path)
93
+ assert_equal 108, file_size_in_bytes
94
+ assert_equal file_size_in_bytes, headers['Content-Length'].to_i
95
+ end
96
+
97
+ def test_headers_does_not_set_vary_header_for_file_without_gzipped_counterpart
98
+ serveable_file = ServeableFile.new(
99
+ :full_path_info => "/thanks.html",
100
+ :path => "#{asset_root}/thanks.html",
101
+ :has_encoding_variants => false,
102
+ :is_gzipped => false
103
+ )
104
+
105
+ headers = serveable_file.headers
106
+
107
+ assert_nil headers['Vary']
108
+ assert_nil headers['Content-Encoding']
109
+ end
110
+
111
+ def test_headers_sets_encoding_related_headers_for_gzipped_asset
112
+ serveable_file = ServeableFile.new(
113
+ :full_path_info => "/assets/application.css",
114
+ :path => "#{asset_root}/assets/application.css.gz",
115
+ :has_encoding_variants => true,
116
+ :is_gzipped => true
117
+ )
118
+
119
+ headers = serveable_file.headers
120
+
121
+ assert_equal 'Accept-Encoding', headers['Vary']
122
+ assert_equal 'gzip', headers['Content-Encoding']
123
+ end
124
+
125
+ def test_headers_sets_vary_header_for_uncompressed_asset_with_gzipped_counterpart
126
+ serveable_file = ServeableFile.new(
127
+ :full_path_info => "/assets/application.css",
128
+ :path => "#{asset_root}/assets/application.css",
129
+ :has_encoding_variants => true,
130
+ :is_gzipped => false
131
+ )
132
+
133
+ headers = serveable_file.headers
134
+
135
+ assert_equal 'Accept-Encoding', headers['Vary']
136
+ assert_nil headers['Content-Encoding']
137
+ end
138
+
139
+ def test_headers_sets_content_type_header_for_gzipped_asset
140
+ serveable_file = ServeableFile.new(
141
+ :full_path_info => "/assets/application.js",
142
+ :path => "#{asset_root}/assets/application.js.gz",
143
+ :has_encoding_variants => true,
144
+ :is_gzipped => true
145
+ )
146
+
147
+ headers = serveable_file.headers
148
+
149
+ assert_equal "application/javascript", headers['Content-Type']
150
+ end
151
+
152
+ def test_response_body_returns_file_contents_in_array_as_required_by_rack
153
+ path = "#{asset_root}/thanks.html"
154
+
155
+ serveable_file = ServeableFile.new(
156
+ :path => path,
157
+ :has_encoding_variants => false
158
+ )
159
+
160
+ assert_equal [::File.read(path)], serveable_file.response_body
161
+ end
162
+
163
+ def test_has_encoding_variants_must_be_given_as_constructor_option_to_ensure_vary_encoding_header_can_be_determined
164
+ e = assert_raises ArgumentError do
165
+ ServeableFile.new({})
166
+ end
167
+ assert_equal ':has_encoding_variants option must be given', e.message
168
+ end
169
+
170
+ def test_encoding_variants_returns_true_when_constructor_option_true
171
+ serveable_file = ServeableFile.new(:has_encoding_variants => true)
172
+ assert serveable_file.encoding_variants?
173
+ end
174
+
175
+ def test_encoding_variants_returns_false_when_constructor_option_false
176
+ serveable_file = ServeableFile.new(:has_encoding_variants => false)
177
+ assert !serveable_file.encoding_variants?
178
+ end
179
+
180
+ def test_gzipped_returns_false_when_constructor_option_false
181
+ serveable_file = ServeableFile.new(:is_gzipped => false, :has_encoding_variants => true)
182
+ assert !serveable_file.gzipped?
183
+ end
184
+
185
+ def test_gzipped_returns_true_when_constructor_option_true
186
+ serveable_file = ServeableFile.new(:is_gzipped => true, :has_encoding_variants => true)
187
+ assert serveable_file.gzipped?
188
+ end
189
+
190
+ def test_gzipped_defaults_to_false_when_no_constructor_option_given
191
+ serveable_file = ServeableFile.new({:has_encoding_variants => true})
192
+ assert !serveable_file.gzipped?
193
+ end
194
+
195
+
196
+ def test_serveable_files_with_same_options_are_equal
197
+ file1 = ServeableFile.new :path => "#{asset_root}/hello/world.html.gz",
198
+ :full_path_info => '/hello/world.html',
199
+ :has_encoding_variants => true,
200
+ :is_gzipped => true
201
+
202
+ file2 = ServeableFile.new :path => "#{asset_root}/hello/world.html.gz",
203
+ :full_path_info => '/hello/world.html',
204
+ :has_encoding_variants => true,
205
+ :is_gzipped => true
206
+
207
+ assert_equal file1, file2
208
+ assert_equal file2, file1
209
+ assert file1.eql?(file2)
210
+ assert file2.eql?(file1)
211
+ end
212
+
213
+ def test_serveable_files_with_different_paths_are_not_equal
214
+ file1 = ServeableFile.new :path => "#{asset_root}/hello/world.html.gz",
215
+ :full_path_info => '/hello/world.html',
216
+ :has_encoding_variants => true,
217
+ :is_gzipped => true
218
+
219
+ file2 = ServeableFile.new :path => "#{asset_root}/foo/bar.html.gz",
220
+ :full_path_info => '/hello/world.html',
221
+ :has_encoding_variants => true,
222
+ :is_gzipped => true
223
+
224
+ assert_not_equal file1, file2
225
+ assert_not_equal file2, file1
226
+ assert !file1.eql?(file2)
227
+ assert !file2.eql?(file1)
228
+ end
229
+
230
+ def test_serveable_files_with_different_path_info_are_not_equal
231
+ file1 = ServeableFile.new :path => "#{asset_root}/hello/world.html.gz",
232
+ :full_path_info => '/hello/world.html',
233
+ :has_encoding_variants => true,
234
+ :is_gzipped => true
235
+
236
+ file2 = ServeableFile.new :path => "#{asset_root}/hello/world.html.gz",
237
+ :full_path_info => '/foo/bar.html',
238
+ :has_encoding_variants => true,
239
+ :is_gzipped => true
240
+
241
+ assert_not_equal file1, file2
242
+ assert_not_equal file2, file1
243
+ assert !file1.eql?(file2)
244
+ assert !file2.eql?(file1)
245
+ end
246
+
247
+ def test_serveable_files_with_different_has_encoding_variants_are_not_equal
248
+ file1 = ServeableFile.new :path => "#{asset_root}/hello/world.html.gz",
249
+ :full_path_info => '/hello/world.html',
250
+ :has_encoding_variants => true,
251
+ :is_gzipped => true
252
+
253
+ file2 = ServeableFile.new :path => "#{asset_root}/hello/world.html.gz",
254
+ :full_path_info => '/hello/world.html',
255
+ :has_encoding_variants => false,
256
+ :is_gzipped => true
257
+
258
+ assert_not_equal file1, file2
259
+ assert_not_equal file2, file1
260
+ assert !file1.eql?(file2)
261
+ assert !file2.eql?(file1)
262
+ end
263
+
264
+ def test_serveable_files_with_different_is_gzipped_are_not_equal
265
+ file1 = ServeableFile.new :path => "#{asset_root}/hello/world.html",
266
+ :full_path_info => '/hello/world.html',
267
+ :has_encoding_variants => true,
268
+ :is_gzipped => false
269
+
270
+ file2 = ServeableFile.new :path => "#{asset_root}/hello/world.html",
271
+ :full_path_info => '/hello/world.html',
272
+ :has_encoding_variants => true,
273
+ :is_gzipped => true
274
+
275
+ assert_not_equal file1, file2
276
+ assert_not_equal file2, file1
277
+ assert !file1.eql?(file2)
278
+ assert !file2.eql?(file1)
279
+ end
280
+
281
+ def test_gzipped_serveable_file_does_not_equal_its_non_gzipped_counterpart
282
+ gzipped = ServeableFile.new :path => "#{asset_root}/hello/world.html.gz",
283
+ :full_path_info => '/hello/world.html',
284
+ :has_encoding_variants => true,
285
+ :is_gzipped => true
286
+
287
+ not_gzipped = ServeableFile.new :path => "#{asset_root}/hello/world.html",
288
+ :full_path_info => '/hello/world.html',
289
+ :has_encoding_variants => true,
290
+ :is_gzipped => false
291
+
292
+ assert_not_equal gzipped, not_gzipped
293
+ assert_not_equal not_gzipped, gzipped
294
+ assert !gzipped.eql?(not_gzipped)
295
+ assert !not_gzipped.eql?(gzipped)
296
+ end
297
+
298
+ def test_find_first_finds_static_file_as_directory
299
+ paths = ['/foo/bar.html', '/foo/bar/', '/foo/bar']
300
+ paths.each do |path|
301
+ serveable_file = ServeableFile.find_first(
302
+ :path_info => path,
303
+ :asset_compiler => NullAssetCompiler.new,
304
+ :asset_root => asset_root,
305
+ :include_gzipped => false
306
+ )
307
+
308
+ assert serveable_file, "ServeableFile should be found for path info '#{path}'"
309
+ assert_equal "#{asset_root}/foo/bar.html", serveable_file.path
310
+ assert_equal "/foo/bar.html", serveable_file.full_path_info
311
+ end
312
+ end
313
+
314
+ def test_find_first_finds_static_index_in_directory
315
+ paths = ['/foo/index.html', '/foo/', '/foo']
316
+ paths.each do |path|
317
+ serveable_file = ServeableFile.find_first(
318
+ :path_info => path,
319
+ :asset_compiler => NullAssetCompiler.new,
320
+ :asset_root => asset_root,
321
+ :include_gzipped => false
322
+ )
323
+
324
+ assert serveable_file, "ServeableFile should be found for path info '#{path}'"
325
+ assert_equal "#{asset_root}/foo/index.html", serveable_file.path
326
+ assert_equal "/foo/index.html", serveable_file.full_path_info
327
+ end
328
+ end
329
+
330
+ def test_find_first_finds_static_index_at_root
331
+ valid_root_paths = [
332
+ '/index.html', '/index', '/', ''
333
+ ]
334
+ valid_root_paths.each do |root|
335
+
336
+ serveable_file = ServeableFile.find_first(
337
+ :path_info => root,
338
+ :asset_compiler => NullAssetCompiler.new,
339
+ :asset_root => asset_root,
340
+ :include_gzipped => false
341
+ )
342
+
343
+ assert serveable_file, "ServeableFile should be found for root path info '#{root}'"
344
+ assert_equal "#{asset_root}/index.html", serveable_file.path
345
+ assert_equal "/index.html", serveable_file.full_path_info
346
+ end
347
+ end
348
+
349
+ def test_find_first_finds_nothing_for_non_static_extension
350
+ assert_nil ServeableFile.find_first(
351
+ :path_info => '/about',
352
+ :asset_compiler => NullAssetCompiler.new,
353
+ :asset_root => asset_root
354
+ )
355
+ end
356
+
357
+ def test_find_first_finds_nothing_for_compileable_path_info
358
+ ::Rails.configuration.assets.compile = true
359
+
360
+ asset_compiler = RailsAssetCompiler.new
361
+
362
+ path_info = '/assets/main.css'
363
+
364
+ assert asset_compiler.compiles?(path_info),
365
+ "asset compiler should compile '#{path_info}'"
366
+
367
+ assert_nil ServeableFile.find_first(
368
+ :path_info => path_info,
369
+ :asset_compiler => asset_compiler
370
+ )
371
+ end
372
+
373
+ def test_find_first_finds_gzip_variant
374
+
375
+ result = ServeableFile.find_first(
376
+ :path_info => "/assets/application.css",
377
+ :asset_compiler => NullAssetCompiler.new,
378
+ :asset_root => asset_root,
379
+ :include_gzipped => true
380
+ )
381
+
382
+ assert_equal "#{asset_root}/assets/application.css.gz", result.path,
383
+ "gzipped file variant should be found"
384
+ assert_equal "/assets/application.css", result.full_path_info
385
+ assert result.encoding_variants?
386
+ assert result.gzipped?
387
+ end
388
+
389
+ def test_find_first_finds_uncompressed_file_when_include_gzipped_false
390
+ result = ServeableFile.find_first(
391
+ :path_info => "/assets/application.css",
392
+ :asset_compiler => NullAssetCompiler.new,
393
+ :asset_root => asset_root,
394
+ :include_gzipped => false
395
+ )
396
+
397
+ assert_equal "#{asset_root}/assets/application.css", result.path,
398
+ "non-gzipped file variant should be found"
399
+ assert_equal "/assets/application.css", result.full_path_info
400
+ assert result.encoding_variants?
401
+ assert !result.gzipped?
402
+ end
403
+
404
+ def test_find_first_finds_uncompressed_file_that_has_no_gzip_variant
405
+ result = ServeableFile.find_first(
406
+ :path_info => "/thanks.html",
407
+ :asset_compiler => NullAssetCompiler.new,
408
+ :asset_root => asset_root,
409
+ :include_gzipped => true
410
+ )
411
+
412
+ assert_equal "#{asset_root}/thanks.html", result.path
413
+ assert_equal "/thanks.html", result.full_path_info
414
+ assert !result.encoding_variants?
415
+ assert !result.gzipped?
416
+ end
417
+
418
+ def test_find_first_finds_nothing_for_static_extension_and_non_existent_file
419
+ assert_nil ServeableFile.find_first(
420
+ :path_info => '/about.html',
421
+ :asset_compiler => NullAssetCompiler.new,
422
+ :asset_root => asset_root,
423
+ :include_gzipped => false
424
+ )
425
+ end
426
+
427
+ def test_has_static_extension_handles_non_lowercase_chars
428
+ ['pNG', 'JPEG', 'HTML', 'HtM', 'GIF', 'Ico'].each do |extension|
429
+ assert ServeableFile.has_static_extension?("/some-asset.#{extension}")
430
+ end
431
+ end
432
+
433
+ def test_has_static_extension_returns_false_for_asset_paths_without_period
434
+ ['/assets/somepng', '/indexhtml', '/assets/applicationcss'].each do |path|
435
+ assert !ServeableFile.has_static_extension?(path)
436
+ end
437
+ end
438
+
439
+ def test_has_static_extension_returns_true_for_fonts
440
+ font_extensions = ['woff', 'woff2', 'ttf', 'eot', 'otf']
441
+ font_extensions.each do |extension|
442
+ assert ServeableFile.has_static_extension?("/comic-sans.#{extension}"),
443
+ "'#{extension}' font extension not recognized"
444
+ end
445
+ end
446
+
447
+ def test_has_static_extension_returns_true_for_flash
448
+ assert ServeableFile.has_static_extension?('/splash-page-like-its-1999.swf'),
449
+ "Should handle flash .swf files"
450
+ end
451
+
452
+ private
453
+
454
+ def assert_last_modified(headers, expected)
455
+ assert_equal expected, headers['Last-Modified']
456
+ end
457
+
458
+ def assert_cache_friendly_last_modified(headers)
459
+ assert_last_modified headers, CACHE_FRIENDLY_LAST_MODIFIED
460
+ end
461
+
462
+ def assert_cache_max_age(headers, expected_duration)
463
+ assert_equal "public, max-age=#{DURATIONS_IN_SECS[expected_duration]}", headers['Cache-Control']
464
+ end
465
+
466
+ end
467
+ end
468
+ end