dassets 0.14.2 → 0.15.1

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 (43) hide show
  1. checksums.yaml +7 -7
  2. data/Gemfile +5 -1
  3. data/README.md +15 -17
  4. data/dassets.gemspec +14 -9
  5. data/lib/dassets.rb +51 -13
  6. data/lib/dassets/asset_file.rb +27 -24
  7. data/lib/dassets/cache.rb +27 -33
  8. data/lib/dassets/config.rb +55 -50
  9. data/lib/dassets/engine.rb +11 -23
  10. data/lib/dassets/file_store.rb +27 -27
  11. data/lib/dassets/server.rb +27 -27
  12. data/lib/dassets/server/request.rb +44 -41
  13. data/lib/dassets/server/response.rb +101 -80
  14. data/lib/dassets/source.rb +15 -9
  15. data/lib/dassets/source_file.rb +103 -82
  16. data/lib/dassets/source_proxy.rb +36 -20
  17. data/lib/dassets/version.rb +3 -1
  18. data/test/helper.rb +31 -25
  19. data/test/support/app.rb +5 -5
  20. data/test/support/empty/{.gitkeep → .keep} +0 -0
  21. data/test/support/factory.rb +3 -2
  22. data/test/support/{public/nested/file3-d41d8cd98f00b204e9800998ecf8427e.txt → linked_source_files/linked_file.txt} +0 -0
  23. data/test/support/source_files/linked +1 -0
  24. data/test/support/source_files/linked_file2.txt +1 -0
  25. data/test/system/rack_tests.rb +65 -61
  26. data/test/unit/asset_file_tests.rb +69 -61
  27. data/test/unit/cache_tests.rb +15 -34
  28. data/test/unit/config_tests.rb +59 -52
  29. data/test/unit/dassets_tests.rb +31 -24
  30. data/test/unit/engine_tests.rb +9 -43
  31. data/test/unit/file_store_tests.rb +44 -31
  32. data/test/unit/server/request_tests.rb +57 -59
  33. data/test/unit/server/response_tests.rb +82 -82
  34. data/test/unit/server_tests.rb +5 -9
  35. data/test/unit/source_file_tests.rb +80 -73
  36. data/test/unit/source_proxy_tests.rb +84 -90
  37. data/test/unit/source_tests.rb +66 -50
  38. data/tmp/.gitkeep +0 -0
  39. metadata +92 -72
  40. data/.gitignore +0 -19
  41. data/test/support/public/file2-9bbe1047cffbb590f59e0e5aeff46ae4.txt +0 -1
  42. data/test/support/public/grumpy_cat-b0d1f399a916f7a25c4c0f693c619013.jpg +0 -0
  43. data/test/support/public/nested/a-thing.txt-7413d18f2eba9c695a880aff67fde135.no-use +0 -4
@@ -1,106 +1,104 @@
1
- require 'assert'
2
- require 'dassets/server/request'
1
+ # frozen_string_literal: true
3
2
 
4
- require 'dassets/asset_file'
3
+ require "assert"
4
+ require "dassets/server/request"
5
5
 
6
- class Dassets::Server::Request
6
+ require "dassets/asset_file"
7
7
 
8
+ class Dassets::Server::Request
8
9
  class UnitTests < Assert::Context
9
10
  desc "Dassets::Server::Request"
11
+ subject{ @req }
12
+
10
13
  setup do
11
- @path = '/file1-daa05c683a4913b268653f7a7e36a5b4.txt'
12
- @req = file_request('GET', @path)
14
+ @path = "/file1-daa05c683a4913b268653f7a7e36a5b4.txt"
15
+ @req = file_request("GET", @path)
13
16
  end
14
- subject{ @req }
15
17
 
16
18
  should have_imeths :dassets_base_url
17
19
  should have_imeths :for_asset_file?, :asset_path, :asset_file
18
20
 
19
- should "know its base url" do
20
- assert_equal Dassets.config.base_url.to_s, subject.dassets_base_url
21
- end
22
-
23
- should "know its path info" do
24
- assert_equal @path, subject.path_info
25
- end
26
-
27
- should "know its asset_path" do
28
- assert_equal 'file1.txt', subject.asset_path
29
- end
30
-
31
- should "know its asset_file" do
32
- assert_equal Dassets['file1.txt'], subject.asset_file
21
+ should "know its attributes" do
22
+ assert_that(subject.dassets_base_url).equals(Dassets.config.base_url.to_s)
23
+ assert_that(subject.path_info).equals(@path)
24
+ assert_that(subject.asset_path).equals("file1.txt")
25
+ assert_that(subject.asset_file).equals(Dassets["file1.txt"])
33
26
  end
34
27
 
35
28
  should "know if it is for an asset file" do
36
29
  # find nested path with matching fingerprint
37
- req = file_request('GET', '/nested/file3-d41d8cd98f00b204e9800998ecf8427e.txt')
38
- assert req.for_asset_file?
30
+ req =
31
+ file_request(
32
+ "GET",
33
+ "/nested/file3-d41d8cd98f00b204e9800998ecf8427e.txt",
34
+ )
35
+ assert_that(req.for_asset_file?).is_true
39
36
 
40
37
  # find not nested path with matching fingerprint
41
- req = file_request('HEAD', '/file1-daa05c683a4913b268653f7a7e36a5b4.txt')
42
- assert req.for_asset_file?
43
-
44
- # find even if fingerprint is *not* matching - just need to have any fingerprint
45
- req = file_request('GET', '/file1-d41d8cd98f00b204e9800998ecf8427e.txt')
46
- assert req.for_asset_file?
47
-
48
- # no find on invalid fingerprint
49
- req = file_request('GET', '/file1-daa05c683a4913b268653f7a7e36a.txt')
50
- assert_not req.for_asset_file?
51
-
52
- # no find on missing fingerprint
53
- req = file_request('HEAD', '/file1.txt')
54
- assert_not req.for_asset_file?
55
-
56
- # no find on unknown file
57
- req = file_request('GET', '/some-file.txt')
58
- assert_not req.for_asset_file?
59
-
60
- # no find on unknown file with an fingerprint
61
- req = file_request('GET', '/some-file-daa05c683a4913b268653f7a7e36a5b4.txt')
62
- assert_not req.for_asset_file?
38
+ req = file_request("HEAD", "/file1-daa05c683a4913b268653f7a7e36a5b4.txt")
39
+ assert_that(req.for_asset_file?).is_true
40
+
41
+ # find even if fingerprint is *not* matching - just need to have any
42
+ # fingerprint
43
+ req = file_request("GET", "/file1-d41d8cd98f00b204e9800998ecf8427e.txt")
44
+ assert_that(req.for_asset_file?).is_true
45
+
46
+ # not find an invalid fingerprint
47
+ req = file_request("GET", "/file1-abc123.txt")
48
+ assert_that(req.for_asset_file?).is_false
49
+
50
+ # not find a missing fingerprint
51
+ req = file_request("HEAD", "/file1.txt")
52
+ assert_that(req.for_asset_file?).is_false
53
+
54
+ # not find an unknown file with a missing fingerprint
55
+ req = file_request("GET", "/some-file.txt")
56
+ assert_that(req.for_asset_file?).is_false
57
+
58
+ # not find an unknown file with a valid fingerprint
59
+ req =
60
+ file_request("GET", "/some-file-daa05c683a4913b268653f7a7e36a5b4.txt")
61
+ assert_that(req.for_asset_file?).is_false
63
62
  end
64
63
 
65
- should "return an asset path and an empty asset file if request not for asset file" do
66
- req = file_request('GET', '/some-file.txt')
64
+ should "return an empty path and file if request not for an asset file" do
65
+ req = file_request("GET", "/some-file.txt")
67
66
 
68
- assert_equal '', req.asset_path
69
- assert_equal Dassets::AssetFile.new(''), req.asset_file
67
+ assert_that(req.asset_path).equals("")
68
+ assert_that(req.asset_file).equals(Dassets::AssetFile.new(""))
70
69
  end
71
70
 
72
- protected
71
+ private
73
72
 
74
73
  def file_request(method, path_info)
75
- require 'dassets/server/request'
76
74
  Dassets::Server::Request.new({
77
- 'REQUEST_METHOD' => method,
78
- 'PATH_INFO' => path_info
75
+ "REQUEST_METHOD" => method,
76
+ "PATH_INFO" => path_info,
79
77
  })
80
78
  end
81
-
82
79
  end
83
80
 
84
81
  class BaseUrlTests < UnitTests
85
82
  desc "when a base url is configured"
83
+
86
84
  setup do
87
85
  @orig_base_url = Dassets.config.base_url
88
86
  @new_base_url = Factory.url
89
87
  Dassets.config.base_url(@new_base_url)
90
88
  end
89
+
91
90
  teardown do
92
91
  Dassets.config.set_base_url(@orig_base_url)
93
92
  end
94
93
 
95
94
  should "have the same base url as is configured" do
96
- assert_equal @new_base_url.to_s, subject.dassets_base_url
95
+ assert_that(subject.dassets_base_url).equals(@new_base_url.to_s)
97
96
  end
98
97
 
99
98
  should "remove the configured base url from the path info" do
100
- assert_equal @path, file_request('GET', @path).path_info
101
- assert_equal @path, file_request('GET', "#{@new_base_url}#{@path}").path_info
99
+ assert_that(file_request("GET", @path).path_info).equals(@path)
100
+ assert_that(file_request("GET", "#{@new_base_url}#{@path}").path_info)
101
+ .equals(@path)
102
102
  end
103
-
104
103
  end
105
-
106
104
  end
@@ -1,77 +1,80 @@
1
- require 'assert'
2
- require 'dassets/server/response'
1
+ # frozen_string_literal: true
3
2
 
4
- require 'rack/utils'
5
- require 'dassets/asset_file'
3
+ require "assert"
4
+ require "dassets/server/response"
6
5
 
7
- class Dassets::Server::Response
6
+ require "rack/utils"
7
+ require "dassets/asset_file"
8
8
 
9
+ class Dassets::Server::Response
9
10
  class UnitTests < Assert::Context
10
11
  desc "Dassets::Server::Response"
12
+ subject{ @response }
13
+
11
14
  setup do
12
- @env = {}
13
- @asset_file = Dassets['file1.txt']
15
+ @env = {}
16
+ @asset_file = Dassets["file1.txt"]
14
17
 
15
18
  @response = Dassets::Server::Response.new(@env, @asset_file)
16
19
  end
17
- subject{ @response }
18
20
 
19
21
  should have_readers :asset_file, :status, :headers, :body
20
22
  should have_imeths :to_rack
21
23
 
22
24
  should "handle not modified files" do
23
- env = { 'HTTP_IF_MODIFIED_SINCE' => @asset_file.mtime }
25
+ env = { "HTTP_IF_MODIFIED_SINCE" => @asset_file.mtime }
24
26
  resp = Dassets::Server::Response.new(env, @asset_file)
25
27
 
26
- assert_equal 304, resp.status
27
- assert_equal [], resp.body
28
-
29
- exp_headers = Rack::Utils::HeaderHash.new('Last-Modified' => @asset_file.mtime.to_s)
30
- assert_equal exp_headers, resp.headers
28
+ assert_that(resp.status).equals(304)
29
+ assert_that(resp.body).equals([])
31
30
 
32
- assert_equal [304, exp_headers.to_hash, []], resp.to_rack
31
+ exp_headers =
32
+ Rack::Utils::HeaderHash.new("Last-Modified" => @asset_file.mtime.to_s)
33
+ assert_that(resp.headers).equals(exp_headers)
34
+ assert_that(resp.to_rack).equals([304, exp_headers.to_hash, []])
33
35
  end
34
36
 
35
37
  should "handle found files" do
36
38
  resp = Dassets::Server::Response.new(@env, @asset_file)
37
39
 
38
- assert_equal 200, resp.status
40
+ assert_that(resp.status).equals(200)
39
41
 
40
42
  exp_body = Body.new(@env, @asset_file)
41
- assert_equal exp_body, resp.body
43
+ assert_that(resp.body).equals(exp_body)
42
44
 
43
- exp_headers = @asset_file.response_headers.merge({
44
- 'Content-Type' => 'text/plain',
45
- 'Content-Length' => Rack::Utils.bytesize(@asset_file.content).to_s,
46
- 'Last-Modified' => @asset_file.mtime.to_s
47
- })
48
- assert_equal exp_headers, resp.headers
45
+ exp_headers =
46
+ @asset_file.response_headers.merge({
47
+ "Content-Type" => "text/plain",
48
+ "Content-Length" => @asset_file.size.to_s,
49
+ "Last-Modified" => @asset_file.mtime.to_s,
50
+ })
51
+ assert_that(resp.headers).equals(exp_headers)
49
52
 
50
- assert_equal [200, exp_headers, exp_body], resp.to_rack
53
+ assert_that(resp.to_rack).equals([200, exp_headers, exp_body])
51
54
  end
52
55
 
53
56
  should "have an empty body for found files with a HEAD request" do
54
- env = { 'REQUEST_METHOD' => 'HEAD' }
57
+ env = { "REQUEST_METHOD" => "HEAD" }
55
58
  resp = Dassets::Server::Response.new(env, @asset_file)
56
59
 
57
- assert_equal 200, resp.status
58
- assert_equal [], resp.body
60
+ assert_that(resp.status).equals(200)
61
+ assert_that(resp.body).equals([])
59
62
  end
60
63
 
61
64
  should "handle not found files" do
62
- af = Dassets['not-found-file.txt']
65
+ af = Dassets.asset_file("not-found-file.txt")
63
66
  resp = Dassets::Server::Response.new(@env, af)
64
67
 
65
- assert_equal 404, resp.status
66
- assert_equal ['Not Found'], resp.body
67
- assert_equal Rack::Utils::HeaderHash.new, resp.headers
68
- assert_equal [404, {}, ['Not Found']], resp.to_rack
68
+ assert_that(resp.status).equals(404)
69
+ assert_that(resp.body).equals(["Not Found"])
70
+ assert_that(resp.headers).equals(Rack::Utils::HeaderHash.new)
71
+ assert_that(resp.to_rack).equals([404, {}, ["Not Found"]])
69
72
  end
70
-
71
73
  end
72
74
 
73
75
  class PartialContentTests < UnitTests
74
76
  desc "for a partial content request"
77
+
75
78
  setup do
76
79
  @body = Body.new(@env, @asset_file)
77
80
  Assert.stub(Body, :new).with(@env, @asset_file){ @body }
@@ -84,55 +87,54 @@ class Dassets::Server::Response
84
87
  end
85
88
 
86
89
  should "be a partial content response" do
87
- assert_equal 206, subject.status
90
+ assert_that(subject.status).equals(206)
88
91
 
89
- assert_includes 'Content-Range', subject.headers
90
- assert_equal @body.content_range, subject.headers['Content-Range']
92
+ assert_that(subject.headers).includes("Content-Range")
93
+ assert_that(subject.headers["Content-Range"]).equals(@body.content_range)
91
94
  end
92
-
93
95
  end
94
96
 
95
97
  class BodyTests < UnitTests
96
98
  desc "Body"
99
+ subject{ @body }
100
+
97
101
  setup do
98
102
  @body = Body.new(@env, @asset_file)
99
103
  end
100
- subject{ @body }
101
104
 
102
105
  should have_readers :asset_file, :size, :content_range
103
106
  should have_imeths :partial?, :range_begin, :range_end
104
107
  should have_imeths :each
105
108
 
106
109
  should "know its chunk size" do
107
- assert_equal 8192, Body::CHUNK_SIZE
110
+ assert_that(Body::CHUNK_SIZE).equals(8192)
108
111
  end
109
112
 
110
113
  should "know its asset file" do
111
- assert_equal @asset_file, subject.asset_file
114
+ assert_that(subject.asset_file).equals(@asset_file)
112
115
  end
113
116
 
114
117
  should "know if it is equal to another body" do
115
118
  same_af_same_range = Body.new(@env, @asset_file)
116
119
  Assert.stub(same_af_same_range, :range_begin){ subject.range_begin }
117
120
  Assert.stub(same_af_same_range, :range_end){ subject.range_end }
118
- assert_equal same_af_same_range, subject
121
+ assert_that(subject).equals(same_af_same_range)
119
122
 
120
- other_af_same_range = Body.new(@env, Dassets['file2.txt'])
123
+ other_af_same_range = Body.new(@env, Dassets["file2.txt"])
121
124
  Assert.stub(other_af_same_range, :range_begin){ subject.range_begin }
122
125
  Assert.stub(other_af_same_range, :range_end){ subject.range_end }
123
- assert_not_equal other_af_same_range, subject
126
+ assert_that(subject).does_not_equal(other_af_same_range)
124
127
 
125
128
  same_af_other_range = Body.new(@env, @asset_file)
126
129
 
127
130
  Assert.stub(same_af_other_range, :range_begin){ Factory.integer }
128
131
  Assert.stub(same_af_other_range, :range_end){ subject.range_end }
129
- assert_not_equal same_af_other_range, subject
132
+ assert_that(subject).does_not_equal(same_af_other_range)
130
133
 
131
134
  Assert.stub(same_af_other_range, :range_begin){ subject.range_begin }
132
135
  Assert.stub(same_af_other_range, :range_end){ Factory.integer }
133
- assert_not_equal same_af_other_range, subject
136
+ assert_that(subject).does_not_equal(same_af_other_range)
134
137
  end
135
-
136
138
  end
137
139
 
138
140
  class BodyIOTests < BodyTests
@@ -140,132 +142,130 @@ class Dassets::Server::Response
140
142
  @min_num_chunks = 3
141
143
  @num_chunks = @min_num_chunks + Factory.integer(3)
142
144
 
143
- content = 'a' * (@num_chunks * Body::CHUNK_SIZE)
145
+ content = "a" * (@num_chunks * Body::CHUNK_SIZE)
144
146
  Assert.stub(@asset_file, :content){ content }
145
147
  end
146
-
147
148
  end
148
149
 
149
150
  class NonPartialBodyTests < BodyIOTests
150
151
  desc "for non/multi/invalid partial content requests"
152
+
151
153
  setup do
152
- range = [nil, 'bytes=', 'bytes=0-1,2-3', 'bytes=3-2', 'bytes=abc'].sample
153
- env = range.nil? ? {} : { 'HTTP_RANGE' => range }
154
+ range = [nil, "bytes=", "bytes=0-1,2-3", "bytes=3-2", "bytes=abc"].sample
155
+ env = range.nil? ? {} : { "HTTP_RANGE" => range }
154
156
  @body = Body.new(env, @asset_file)
155
157
  end
156
158
 
157
159
  should "not be partial" do
158
- assert_false subject.partial?
160
+ assert_that(subject.partial?).is_false
159
161
  end
160
162
 
161
163
  should "be the full content size" do
162
- assert_equal @asset_file.size, subject.size
164
+ assert_that(subject.size).equals(@asset_file.size)
163
165
  end
164
166
 
165
167
  should "have no content range" do
166
- assert_nil subject.content_range
168
+ assert_that(subject.content_range).is_nil
167
169
  end
168
170
 
169
171
  should "have the full content size as its range" do
170
- assert_equal 0, subject.range_begin
171
- assert_equal subject.size-1, subject.range_end
172
+ assert_that(subject.range_begin).equals(0)
173
+ assert_that(subject.range_end).equals(subject.size - 1)
172
174
  end
173
175
 
174
176
  should "chunk the full content when iterated" do
175
177
  chunks = []
176
178
  subject.each{ |chunk| chunks << chunk }
177
179
 
178
- assert_equal @num_chunks, chunks.size
179
- assert_equal subject.class::CHUNK_SIZE, chunks.first.size
180
- assert_equal @asset_file.content, chunks.join('')
180
+ assert_that(chunks.size).equals(@num_chunks)
181
+ assert_that(chunks.first.size).equals(subject.class::CHUNK_SIZE)
182
+ assert_that(chunks.join("")).equals(@asset_file.content)
181
183
  end
182
-
183
184
  end
184
185
 
185
186
  class PartialBodySetupTests < BodyIOTests
186
187
  desc "for a partial content request"
188
+
187
189
  setup do
188
190
  @start_chunk = Factory.boolean ? 0 : 1
189
191
  @partial_begin = @start_chunk * Body::CHUNK_SIZE
190
192
  @partial_chunks = @num_chunks - Factory.integer(@min_num_chunks)
191
193
  @partial_size = @partial_chunks * Body::CHUNK_SIZE
192
- @partial_end = @partial_begin + (@partial_size-1)
194
+ @partial_end = @partial_begin + (@partial_size - 1)
193
195
 
194
- @env = { 'HTTP_RANGE' => "bytes=#{@partial_begin}-#{@partial_end}" }
196
+ @env = { "HTTP_RANGE" => "bytes=#{@partial_begin}-#{@partial_end}" }
195
197
  end
196
-
197
198
  end
198
199
 
199
200
  class PartialBodyTests < PartialBodySetupTests
201
+ subject{ @body }
202
+
200
203
  setup do
201
204
  @body = Body.new(@env, @asset_file)
202
205
  end
203
- subject{ @body }
204
206
 
205
207
  should "be partial" do
206
- assert_true subject.partial?
208
+ assert_that(subject.partial?).is_true
207
209
  end
208
210
 
209
211
  should "be the specified partial size" do
210
- assert_equal @partial_size, subject.size
212
+ assert_that(subject.size).equals(@partial_size)
211
213
  end
212
214
 
213
215
  should "know its content range" do
214
216
  exp = "bytes #{@partial_begin}-#{@partial_end}/#{@asset_file.size}"
215
- assert_equal exp, subject.content_range
217
+ assert_that(subject.content_range).equals(exp)
216
218
  end
217
219
 
218
220
  should "have the know its range" do
219
- assert_equal @partial_begin, subject.range_begin
220
- assert_equal @partial_end, subject.range_end
221
+ assert_that(subject.range_begin).equals(@partial_begin)
222
+ assert_that(subject.range_end).equals(@partial_end)
221
223
  end
222
224
 
223
225
  should "chunk the range when iterated" do
224
226
  chunks = []
225
227
  subject.each{ |chunk| chunks << chunk }
226
228
 
227
- assert_equal @partial_chunks, chunks.size
228
- assert_equal subject.class::CHUNK_SIZE, chunks.first.size
229
+ assert_that(chunks.size).equals(@partial_chunks)
230
+ assert_that(chunks.first.size).equals(subject.class::CHUNK_SIZE)
229
231
 
230
232
  exp = @asset_file.content[@partial_begin..@partial_end]
231
- assert_equal exp, chunks.join('')
233
+ assert_that(chunks.join("")).equals(exp)
232
234
  end
233
-
234
235
  end
235
236
 
236
237
  class LegacyRackTests < PartialBodySetupTests
237
238
  desc "when using a legacy version of rack that can't interpret byte ranges"
239
+
238
240
  setup do
239
241
  Assert.stub(Rack::Utils, :respond_to?).with(:byte_ranges){ false }
240
242
  @body = Body.new(@env, @asset_file)
241
243
  end
242
244
 
243
245
  should "not be partial" do
244
- assert_false subject.partial?
246
+ assert_that(subject.partial?).is_false
245
247
  end
246
248
 
247
249
  should "be the full content size" do
248
- assert_equal @asset_file.size, subject.size
250
+ assert_that(subject.size).equals(@asset_file.size)
249
251
  end
250
252
 
251
253
  should "have no content range" do
252
- assert_nil subject.content_range
254
+ assert_that(subject.content_range).is_nil
253
255
  end
254
256
 
255
257
  should "have the full content size as its range" do
256
- assert_equal 0, subject.range_begin
257
- assert_equal subject.size-1, subject.range_end
258
+ assert_that(subject.range_begin).equals(0)
259
+ assert_that(subject.range_end).equals(subject.size - 1)
258
260
  end
259
261
 
260
262
  should "chunk the full content when iterated" do
261
263
  chunks = []
262
264
  subject.each{ |chunk| chunks << chunk }
263
265
 
264
- assert_equal @num_chunks, chunks.size
265
- assert_equal subject.class::CHUNK_SIZE, chunks.first.size
266
- assert_equal @asset_file.content, chunks.join('')
266
+ assert_that(chunks.size).equals(@num_chunks)
267
+ assert_that(chunks.first.size).equals(subject.class::CHUNK_SIZE)
268
+ assert_that(chunks.join("")).equals(@asset_file.content)
267
269
  end
268
-
269
270
  end
270
-
271
271
  end