dassets 0.14.5 → 0.15.0
Sign up to get free protection for your applications and to get access to all the features.
- 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 +20 -18
- data/lib/dassets/asset_file.rb +14 -12
- data/lib/dassets/cache.rb +27 -33
- data/lib/dassets/config.rb +55 -51
- data/lib/dassets/engine.rb +11 -23
- data/lib/dassets/file_store.rb +27 -28
- 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/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 +63 -59
- data/test/unit/cache_tests.rb +14 -35
- data/test/unit/config_tests.rb +53 -49
- data/test/unit/dassets_tests.rb +25 -40
- data/test/unit/engine_tests.rb +7 -43
- data/test/unit/file_store_tests.rb +33 -25
- data/test/unit/server/request_tests.rb +43 -48
- 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 -62
data/lib/dassets/source.rb
CHANGED
@@ -1,14 +1,15 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dassets/engine"
|
2
4
|
|
3
5
|
module Dassets; end
|
4
6
|
class Dassets::Source
|
5
|
-
|
6
7
|
attr_reader :path, :engines, :response_headers
|
7
8
|
|
8
9
|
def initialize(path)
|
9
10
|
@path = path.to_s
|
10
11
|
@filter = proc{ |paths| paths }
|
11
|
-
@engines = Hash.new{ |
|
12
|
+
@engines = Hash.new{ |hash, key| hash[key] = [] }
|
12
13
|
@response_headers = Hash.new
|
13
14
|
end
|
14
15
|
|
@@ -16,10 +17,10 @@ class Dassets::Source
|
|
16
17
|
block.nil? ? @filter : @filter = block
|
17
18
|
end
|
18
19
|
|
19
|
-
def engine(input_ext, engine_class, registered_opts=nil)
|
20
|
-
default_opts = {
|
20
|
+
def engine(input_ext, engine_class, registered_opts = nil)
|
21
|
+
default_opts = { "source_path" => @path }
|
21
22
|
engine_opts = default_opts.merge(registered_opts || {})
|
22
|
-
@engines[input_ext.to_s]
|
23
|
+
@engines[input_ext.to_s] << engine_class.new(engine_opts)
|
23
24
|
end
|
24
25
|
|
25
26
|
def files
|
@@ -28,12 +29,16 @@ class Dassets::Source
|
|
28
29
|
|
29
30
|
private
|
30
31
|
|
32
|
+
# Use "**{,/*/**}/*" to glob following symlinks and returning immediate-child
|
33
|
+
# matches. See https://stackoverflow.com/a/2724048.
|
31
34
|
def glob_files
|
32
|
-
Dir
|
35
|
+
Dir
|
36
|
+
.glob(File.join(@path, "**{,/*/**}/*"))
|
37
|
+
.uniq
|
38
|
+
.reject{ |path| !File.file?(path) }
|
33
39
|
end
|
34
40
|
|
35
41
|
def apply_filter(files)
|
36
42
|
@filter.call(files)
|
37
43
|
end
|
38
|
-
|
39
44
|
end
|
data/lib/dassets/source_file.rb
CHANGED
@@ -1,114 +1,132 @@
|
|
1
|
-
|
2
|
-
require 'dassets'
|
3
|
-
require 'dassets/asset_file'
|
4
|
-
require 'dassets/source_proxy'
|
1
|
+
# frozen_string_literal: true
|
5
2
|
|
6
|
-
|
3
|
+
require "fileutils"
|
4
|
+
require "dassets"
|
5
|
+
require "dassets/asset_file"
|
6
|
+
require "dassets/source_proxy"
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
8
|
+
module Dassets; end
|
9
|
+
class Dassets::SourceFile
|
10
|
+
def self.find_by_digest_path(path, **options)
|
11
|
+
Dassets.source_files[path] || Dassets::NullSourceFile.new(path, **options)
|
12
|
+
end
|
13
13
|
|
14
|
-
|
14
|
+
attr_reader :file_path
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
16
|
+
def initialize(file_path)
|
17
|
+
@file_path = file_path.to_s
|
18
|
+
@ext_list = File.basename(@file_path).split(".").reverse
|
19
|
+
end
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
21
|
+
# Get the last matching one (in the case two sources with the same path are
|
22
|
+
# configured) since we select the last matching source file (from the last
|
23
|
+
# configured source) in `find_by_digest_path` above.
|
24
|
+
def source
|
25
|
+
@source ||=
|
26
|
+
Dassets.config.sources.select { |source|
|
26
27
|
@file_path =~ /^#{slash_path(source.path)}/
|
27
|
-
|
28
|
-
|
28
|
+
}.last
|
29
|
+
end
|
29
30
|
|
30
|
-
|
31
|
-
|
32
|
-
|
31
|
+
def asset_file
|
32
|
+
@asset_file ||= Dassets::AssetFile.new(self.digest_path)
|
33
|
+
end
|
33
34
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
35
|
+
def digest_path
|
36
|
+
@digest_path ||=
|
37
|
+
begin
|
38
|
+
digest_basename =
|
39
|
+
@ext_list
|
40
|
+
.reduce([]) { |digest_ext_list, ext|
|
41
|
+
digest_ext_list <<
|
42
|
+
self.source.engines[ext].reduce(ext) { |ext_acc, engine|
|
43
|
+
engine.ext(ext_acc)
|
44
|
+
}
|
45
|
+
}
|
46
|
+
.reject(&:empty?)
|
47
|
+
.reverse
|
48
|
+
.join(".")
|
39
49
|
|
40
50
|
File.join([digest_dirname(@file_path), digest_basename].reject(&:empty?))
|
41
51
|
end
|
42
|
-
|
52
|
+
end
|
43
53
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
54
|
+
def compiled
|
55
|
+
@ext_list.reduce(read_file(@file_path)) { |file_acc, ext|
|
56
|
+
self.source.engines[ext].reduce(file_acc) { |ext_acc, engine|
|
57
|
+
engine.compile(ext_acc)
|
58
|
+
}
|
59
|
+
}
|
60
|
+
end
|
49
61
|
|
50
|
-
|
51
|
-
|
52
|
-
|
62
|
+
def exists?
|
63
|
+
File.file?(@file_path)
|
64
|
+
end
|
53
65
|
|
54
|
-
|
55
|
-
|
56
|
-
|
66
|
+
def mtime
|
67
|
+
File.mtime(@file_path)
|
68
|
+
end
|
57
69
|
|
58
|
-
|
59
|
-
|
60
|
-
|
70
|
+
def response_headers
|
71
|
+
self.source.nil? ? Hash.new : self.source.response_headers
|
72
|
+
end
|
61
73
|
|
62
|
-
|
74
|
+
def ==(other_source_file)
|
75
|
+
if other_source_file.is_a?(self.class)
|
63
76
|
self.file_path == other_source_file.file_path
|
77
|
+
else
|
78
|
+
super
|
64
79
|
end
|
80
|
+
end
|
65
81
|
|
66
|
-
|
67
|
-
|
68
|
-
# remove the source path from the dirname (if it exists)
|
69
|
-
def digest_dirname(file_path)
|
70
|
-
slash_path(File.dirname(file_path)).sub(slash_path(self.source.path), '')
|
71
|
-
end
|
72
|
-
|
73
|
-
def slash_path(path)
|
74
|
-
File.join(path, '')
|
75
|
-
end
|
76
|
-
|
77
|
-
def read_file(path)
|
78
|
-
File.send(File.respond_to?(:binread) ? :binread : :read, path.to_s)
|
79
|
-
end
|
82
|
+
private
|
80
83
|
|
84
|
+
# remove the source path from the dirname (if it exists)
|
85
|
+
def digest_dirname(file_path)
|
86
|
+
slash_path(File.dirname(file_path)).sub(slash_path(self.source.path), "")
|
81
87
|
end
|
82
88
|
|
83
|
-
|
84
|
-
|
89
|
+
def slash_path(path)
|
90
|
+
File.join(path, "")
|
91
|
+
end
|
85
92
|
|
86
|
-
|
93
|
+
def read_file(path)
|
94
|
+
File.send(File.respond_to?(:binread) ? :binread : :read, path.to_s)
|
95
|
+
end
|
96
|
+
end
|
87
97
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
98
|
+
# A null source file is used to represent source that either doesn't exist
|
99
|
+
# or source that is a proxy (ie a combination)
|
100
|
+
class Dassets::NullSourceFile < Dassets::SourceFile
|
101
|
+
def initialize(digest_path, **options)
|
102
|
+
@file_path = ""
|
103
|
+
@ext_list = []
|
104
|
+
@digest_path = digest_path
|
105
|
+
@source_proxy =
|
106
|
+
if Dassets.config.combination?(@digest_path)
|
107
|
+
Dassets::SourceProxy.new(@digest_path, **options)
|
93
108
|
else
|
94
|
-
NullSourceProxy.new
|
109
|
+
Dassets::NullSourceProxy.new
|
95
110
|
end
|
96
|
-
|
97
|
-
|
98
|
-
def compiled; @source_proxy.content; end
|
99
|
-
def exists?; @source_proxy.exists?; end
|
100
|
-
def mtime; @source_proxy.mtime; end
|
111
|
+
end
|
101
112
|
|
102
|
-
|
103
|
-
|
104
|
-
|
113
|
+
def compiled
|
114
|
+
@source_proxy.content
|
115
|
+
end
|
105
116
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
def mtime; nil; end
|
110
|
-
end
|
117
|
+
def exists?
|
118
|
+
@source_proxy.exists?
|
119
|
+
end
|
111
120
|
|
121
|
+
def mtime
|
122
|
+
@source_proxy.mtime
|
112
123
|
end
|
113
124
|
|
125
|
+
def ==(other_source_file)
|
126
|
+
if other_source_file.is_a?(self.class)
|
127
|
+
self.file_path == other_source_file.file_path
|
128
|
+
else
|
129
|
+
super
|
130
|
+
end
|
131
|
+
end
|
114
132
|
end
|
data/lib/dassets/source_proxy.rb
CHANGED
@@ -1,22 +1,25 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "digest/md5"
|
4
|
+
require "dassets/cache"
|
5
|
+
require "dassets/source_file"
|
4
6
|
|
5
7
|
module Dassets; end
|
6
|
-
class Dassets::SourceProxy
|
7
8
|
|
9
|
+
class Dassets::SourceProxy
|
8
10
|
attr_reader :digest_path, :content_cache, :fingerprint_cache
|
9
11
|
attr_reader :source_files
|
10
12
|
|
11
|
-
def initialize(digest_path, options
|
12
|
-
options ||= {}
|
13
|
+
def initialize(digest_path, **options)
|
13
14
|
@digest_path = digest_path
|
14
|
-
@content_cache = options[:content_cache] || Dassets::
|
15
|
-
@fingerprint_cache = options[:fingerprint_cache] || Dassets::
|
16
|
-
@source_files =
|
17
|
-
|
18
|
-
|
19
|
-
|
15
|
+
@content_cache = options[:content_cache] || Dassets::NoCache.new
|
16
|
+
@fingerprint_cache = options[:fingerprint_cache] || Dassets::NoCache.new
|
17
|
+
@source_files =
|
18
|
+
get_source_files(
|
19
|
+
@digest_path,
|
20
|
+
content_cache: @content_cache,
|
21
|
+
fingerprint_cache: @fingerprint_cache,
|
22
|
+
)
|
20
23
|
end
|
21
24
|
|
22
25
|
def key
|
@@ -53,10 +56,23 @@ class Dassets::SourceProxy
|
|
53
56
|
Digest::MD5.new.hexdigest(source_content)
|
54
57
|
end
|
55
58
|
|
56
|
-
def get_source_files(digest_path, options)
|
57
|
-
Dassets.config.combinations[digest_path.to_s].map
|
58
|
-
Dassets::SourceFile.find_by_digest_path(source_digest_path, options)
|
59
|
-
|
59
|
+
def get_source_files(digest_path, **options)
|
60
|
+
Dassets.config.combinations[digest_path.to_s].map { |source_digest_path|
|
61
|
+
Dassets::SourceFile.find_by_digest_path(source_digest_path, **options)
|
62
|
+
}
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
class Dassets::NullSourceProxy
|
67
|
+
def content
|
68
|
+
nil
|
69
|
+
end
|
70
|
+
|
71
|
+
def exists?
|
72
|
+
false
|
60
73
|
end
|
61
74
|
|
75
|
+
def mtime
|
76
|
+
nil
|
77
|
+
end
|
62
78
|
end
|
data/lib/dassets/version.rb
CHANGED
data/test/helper.rb
CHANGED
@@ -5,39 +5,33 @@
|
|
5
5
|
$LOAD_PATH.unshift(File.expand_path("../..", __FILE__))
|
6
6
|
|
7
7
|
# require pry for debugging (`binding.pry`)
|
8
|
-
require
|
8
|
+
require "pry"
|
9
9
|
|
10
|
-
require
|
10
|
+
require "test/support/factory"
|
11
11
|
|
12
|
-
|
12
|
+
require "pathname"
|
13
|
+
TEST_SUPPORT_PATH = Pathname.new(File.expand_path("../support", __FILE__))
|
13
14
|
|
14
|
-
|
15
|
-
if !(a = Array.new).respond_to?(:sample) && a.respond_to?(:choice)
|
16
|
-
class Array
|
17
|
-
alias_method :sample, :choice
|
18
|
-
end
|
19
|
-
end
|
15
|
+
ENV["DASSETS_TEST_MODE"] = "yes"
|
20
16
|
|
21
|
-
require
|
22
|
-
TEST_SUPPORT_PATH = Pathname.new(File.expand_path('../support', __FILE__))
|
17
|
+
require "dassets"
|
23
18
|
|
24
|
-
|
25
|
-
|
26
|
-
|
19
|
+
@dumb_engine =
|
20
|
+
Class.new(Dassets::Engine) do
|
21
|
+
def ext(in_ext); ""; end
|
22
|
+
def compile(input); "#{input}\nDUMB"; end
|
23
|
+
end
|
27
24
|
|
28
|
-
@
|
29
|
-
|
30
|
-
|
31
|
-
end
|
32
|
-
|
33
|
-
def ext(in_ext); 'no-use'; end
|
34
|
-
def compile(input); "#{input}\nUSELESS"; end
|
35
|
-
end
|
25
|
+
@useless_engine =
|
26
|
+
Class.new(Dassets::Engine) do
|
27
|
+
def ext(in_ext); "no-use"; end
|
28
|
+
def compile(input); "#{input}\nUSELESS"; end
|
29
|
+
end
|
36
30
|
|
37
31
|
Dassets.configure do |c|
|
38
32
|
c.source TEST_SUPPORT_PATH.join("app/assets") do |s|
|
39
|
-
s.engine
|
40
|
-
s.engine
|
33
|
+
s.engine "dumb", @dumb_engine
|
34
|
+
s.engine "useless", @useless_engine
|
41
35
|
s.response_headers[Factory.string] = Factory.string
|
42
36
|
end
|
43
37
|
end
|
data/test/support/app.rb
CHANGED
@@ -1,10 +1,8 @@
|
|
1
|
-
require
|
1
|
+
require "sinatra/base"
|
2
2
|
|
3
3
|
class SinatraApp < Sinatra::Base
|
4
|
-
|
5
4
|
configure do
|
6
|
-
set :root,
|
7
|
-
set :public_dir, File.expand_path(
|
5
|
+
set :root, File.expand_path("..", __FILE__)
|
6
|
+
set :public_dir, File.expand_path("./app_public", __FILE__)
|
8
7
|
end
|
9
|
-
|
10
8
|
end
|
data/test/support/factory.rb
CHANGED
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
../linked_source_files/
|
@@ -0,0 +1 @@
|
|
1
|
+
../linked_source_files/linked_file.txt
|
data/test/system/rack_tests.rb
CHANGED
@@ -1,13 +1,12 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "assert"
|
2
|
+
require "dassets"
|
3
3
|
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
4
|
+
require "assert-rack-test"
|
5
|
+
require "fileutils"
|
6
|
+
require "dassets/server"
|
7
|
+
require "test/support/app"
|
8
8
|
|
9
9
|
module Dassets
|
10
|
-
|
11
10
|
class RackTests < Assert::Context
|
12
11
|
include Assert::Rack::Test
|
13
12
|
|
@@ -19,121 +18,118 @@ module Dassets
|
|
19
18
|
def app
|
20
19
|
@app ||= SinatraApp
|
21
20
|
end
|
22
|
-
|
23
21
|
end
|
24
22
|
|
25
23
|
class SuccessTests < RackTests
|
26
24
|
desc "requesting an existing asset file"
|
27
25
|
|
28
26
|
should "return a successful response" do
|
29
|
-
resp = get
|
30
|
-
|
31
|
-
|
27
|
+
resp = get "/file1-daa05c683a4913b268653f7a7e36a5b4.txt"
|
28
|
+
|
29
|
+
assert_that(resp.status).equals(200)
|
30
|
+
assert_that(resp.body).equals(Dassets["file1.txt"].content)
|
32
31
|
end
|
33
32
|
|
34
33
|
should "return a successful response with no body on HEAD requests" do
|
35
|
-
resp = head
|
36
|
-
|
37
|
-
|
38
|
-
|
34
|
+
resp = head "/file2-9bbe1047cffbb590f59e0e5aeff46ae4.txt"
|
35
|
+
|
36
|
+
assert_that(resp.status).equals(200)
|
37
|
+
assert_that(resp.headers["Content-Length"])
|
38
|
+
.equals(Dassets["file2.txt"].size.to_s)
|
39
|
+
assert_that(resp.body).is_empty
|
39
40
|
end
|
40
41
|
|
41
42
|
should "return a partial content response on valid partial content requests" do
|
42
|
-
content = Dassets[
|
43
|
+
content = Dassets["file1.txt"].content
|
43
44
|
size = Factory.integer(content.length)
|
44
|
-
|
45
45
|
# see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35
|
46
|
-
env = {
|
46
|
+
env = { "HTTP_RANGE" => "bytes=0-#{size}" }
|
47
|
+
resp = get "/file1-daa05c683a4913b268653f7a7e36a5b4.txt", {}, env
|
47
48
|
|
48
|
-
resp
|
49
|
-
|
50
|
-
assert_equal content[0..size], resp.body
|
49
|
+
assert_that(resp.status).equals(206)
|
50
|
+
assert_that(resp.body).equals(content[0..size])
|
51
51
|
end
|
52
52
|
|
53
53
|
should "return a full response on no-range partial content requests" do
|
54
54
|
# see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35
|
55
|
-
env = {
|
55
|
+
env = { "HTTP_RANGE" => "bytes=" }
|
56
|
+
resp = get "/file1-daa05c683a4913b268653f7a7e36a5b4.txt", {}, env
|
56
57
|
|
57
|
-
resp
|
58
|
-
|
59
|
-
assert_equal Dassets['file1.txt'].content, resp.body
|
58
|
+
assert_that(resp.status).equals(200)
|
59
|
+
assert_that(resp.body).equals(Dassets["file1.txt"].content)
|
60
60
|
end
|
61
61
|
|
62
62
|
should "return a full response on multiple-range partial content requests" do
|
63
63
|
# see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35
|
64
|
-
env = {
|
64
|
+
env = { "HTTP_RANGE" => "bytes=0-1,2-3" }
|
65
|
+
resp = get "/file1-daa05c683a4913b268653f7a7e36a5b4.txt", {}, env
|
65
66
|
|
66
|
-
resp
|
67
|
-
|
68
|
-
assert_equal Dassets['file1.txt'].content, resp.body
|
67
|
+
assert_that(resp.status).equals(200)
|
68
|
+
assert_that(resp.body).equals(Dassets["file1.txt"].content)
|
69
69
|
end
|
70
70
|
|
71
71
|
should "return a full response on invalid-range partial content requests" do
|
72
72
|
# see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35
|
73
|
-
env = {
|
73
|
+
env = { "HTTP_RANGE" => ["bytes=3-2", "bytes=abc"].sample }
|
74
|
+
resp = get "/file1-daa05c683a4913b268653f7a7e36a5b4.txt", {}, env
|
74
75
|
|
75
|
-
resp
|
76
|
-
|
77
|
-
assert_equal Dassets['file1.txt'].content, resp.body
|
76
|
+
assert_that(resp.status).equals(200)
|
77
|
+
assert_that(resp.body).equals(Dassets["file1.txt"].content)
|
78
78
|
end
|
79
|
-
|
80
79
|
end
|
81
80
|
|
82
81
|
class DigestTests < SuccessTests
|
83
82
|
setup do
|
84
83
|
base_url = Factory.base_url
|
85
84
|
Assert.stub(Dassets.config, :base_url){ base_url }
|
86
|
-
Dassets.config.file_store TEST_SUPPORT_PATH.join(
|
87
|
-
@url = Dassets[
|
85
|
+
Dassets.config.file_store TEST_SUPPORT_PATH.join("public").to_s
|
86
|
+
@url = Dassets["file1.txt"].url
|
88
87
|
@url_file = Dassets.config.file_store.store_path(@url)
|
89
88
|
end
|
89
|
+
|
90
90
|
teardown do
|
91
91
|
FileUtils.rm(@url_file)
|
92
|
-
Dassets.config.file_store
|
92
|
+
Dassets.config.file_store Dassets::NullFileStore.new
|
93
93
|
end
|
94
94
|
|
95
95
|
should "digest the asset" do
|
96
|
-
|
96
|
+
assert_that(@url_file).is_not_a_file
|
97
97
|
|
98
98
|
resp = get @url
|
99
|
-
|
100
|
-
|
99
|
+
assert_that(resp.status).equals(200)
|
100
|
+
assert_that(@url_file).is_a_file
|
101
101
|
end
|
102
|
-
|
103
102
|
end
|
104
103
|
|
105
104
|
class NotModifiedTests < RackTests
|
106
105
|
desc "requesting an existing asset file that has not been modified"
|
107
|
-
setup do
|
108
|
-
@resp = get('/file1-daa05c683a4913b268653f7a7e36a5b4.txt', {}, {
|
109
|
-
'HTTP_IF_MODIFIED_SINCE' => Dassets['file1.txt'].mtime.to_s
|
110
|
-
})
|
111
|
-
end
|
112
106
|
|
113
107
|
should "return a successful response" do
|
114
|
-
|
115
|
-
|
116
|
-
|
108
|
+
resp =
|
109
|
+
get("/file1-daa05c683a4913b268653f7a7e36a5b4.txt", {}, {
|
110
|
+
"HTTP_IF_MODIFIED_SINCE" => Dassets["file1.txt"].mtime.to_s
|
111
|
+
})
|
117
112
|
|
113
|
+
assert_that(resp.status).equals(304)
|
114
|
+
assert_that(resp.body).is_empty
|
115
|
+
end
|
118
116
|
end
|
119
117
|
|
120
118
|
class NotFoundTests < RackTests
|
121
119
|
desc "requesting an non-existing asset file"
|
122
120
|
|
123
121
|
should "return a not found response" do
|
124
|
-
resp = get
|
125
|
-
|
122
|
+
resp = get "/file1-daa05c683a4913b268.txt"
|
123
|
+
assert_that(resp.status).equals(404)
|
126
124
|
|
127
|
-
get
|
128
|
-
|
125
|
+
resp = get "/file1-.txt"
|
126
|
+
assert_that(resp.status).equals(404)
|
129
127
|
|
130
|
-
get
|
131
|
-
|
128
|
+
resp = get "/file1.txt"
|
129
|
+
assert_that(resp.status).equals(404)
|
132
130
|
|
133
|
-
get
|
134
|
-
|
131
|
+
resp = get "/something-not-found"
|
132
|
+
assert_that(resp.status).equals(404)
|
135
133
|
end
|
136
|
-
|
137
134
|
end
|
138
|
-
|
139
135
|
end
|