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