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.
Files changed (41) hide show
  1. checksums.yaml +7 -7
  2. data/.ruby-version +1 -0
  3. data/Gemfile +3 -1
  4. data/README.md +15 -17
  5. data/dassets.gemspec +7 -6
  6. data/lib/dassets.rb +54 -11
  7. data/lib/dassets/asset_file.rb +14 -12
  8. data/lib/dassets/cache.rb +27 -33
  9. data/lib/dassets/config.rb +55 -47
  10. data/lib/dassets/engine.rb +11 -23
  11. data/lib/dassets/file_store.rb +27 -27
  12. data/lib/dassets/server.rb +27 -28
  13. data/lib/dassets/server/request.rb +43 -41
  14. data/lib/dassets/server/response.rb +93 -81
  15. data/lib/dassets/source.rb +13 -8
  16. data/lib/dassets/source_file.rb +100 -82
  17. data/lib/dassets/source_proxy.rb +32 -16
  18. data/lib/dassets/version.rb +3 -1
  19. data/test/helper.rb +18 -24
  20. data/test/support/app.rb +3 -5
  21. data/test/support/factory.rb +1 -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 +55 -59
  26. data/test/unit/asset_file_tests.rb +64 -60
  27. data/test/unit/cache_tests.rb +14 -35
  28. data/test/unit/config_tests.rb +65 -45
  29. data/test/unit/dassets_tests.rb +41 -23
  30. data/test/unit/engine_tests.rb +7 -43
  31. data/test/unit/file_store_tests.rb +42 -31
  32. data/test/unit/server/request_tests.rb +48 -53
  33. data/test/unit/server/response_tests.rb +79 -81
  34. data/test/unit/server_tests.rb +3 -9
  35. data/test/unit/source_file_tests.rb +73 -72
  36. data/test/unit/source_proxy_tests.rb +78 -89
  37. data/test/unit/source_tests.rb +58 -50
  38. metadata +78 -70
  39. data/test/support/public/file2-9bbe1047cffbb590f59e0e5aeff46ae4.txt +0 -1
  40. data/test/support/public/grumpy_cat-b0d1f399a916f7a25c4c0f693c619013.jpg +0 -0
  41. data/test/support/public/nested/a-thing.txt-7413d18f2eba9c695a880aff67fde135.no-use +0 -4
@@ -1,14 +1,15 @@
1
- require 'dassets/engine'
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{ |h,k| Dassets::NullEngine.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 = { 'source_path' => @path }
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] = engine_class.new(engine_opts)
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.glob(File.join(@path, "**/*")).reject!{ |p| !File.file?(p) }
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
@@ -1,114 +1,132 @@
1
- require 'fileutils'
2
- require 'dassets'
3
- require 'dassets/asset_file'
4
- require 'dassets/source_proxy'
1
+ # frozen_string_literal: true
5
2
 
6
- module Dassets
3
+ require "fileutils"
4
+ require "dassets"
5
+ require "dassets/asset_file"
6
+ require "dassets/source_proxy"
7
7
 
8
- class SourceFile
9
-
10
- def self.find_by_digest_path(path, options = nil)
11
- Dassets.source_files[path] || NullSourceFile.new(path, options)
12
- end
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
- attr_reader :file_path
14
+ attr_reader :file_path
15
15
 
16
- def initialize(file_path)
17
- @file_path = file_path.to_s
18
- @ext_list = File.basename(@file_path).split('.').reverse
19
- end
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
- # 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 ||= Dassets.config.sources.select do |source|
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
- end.last
28
- end
28
+ }.last
29
+ end
29
30
 
30
- def asset_file
31
- @asset_file ||= Dassets::AssetFile.new(self.digest_path)
32
- end
31
+ def asset_file
32
+ @asset_file ||= Dassets::AssetFile.new(self.digest_path)
33
+ end
33
34
 
34
- def digest_path
35
- @digest_path ||= begin
36
- digest_basename = @ext_list.inject([]) do |digest_ext_list, ext|
37
- digest_ext_list << self.source.engines[ext].ext(ext)
38
- end.reject(&:empty?).reverse.join('.')
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
- end
52
+ end
43
53
 
44
- def compiled
45
- @ext_list.inject(read_file(@file_path)) do |content, ext|
46
- self.source.engines[ext].compile(content)
47
- end
48
- end
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
- def exists?
51
- File.file?(@file_path)
52
- end
62
+ def exists?
63
+ File.file?(@file_path)
64
+ end
53
65
 
54
- def mtime
55
- File.mtime(@file_path)
56
- end
66
+ def mtime
67
+ File.mtime(@file_path)
68
+ end
57
69
 
58
- def response_headers
59
- self.source.nil? ? Hash.new : self.source.response_headers
60
- end
70
+ def response_headers
71
+ self.source.nil? ? Hash.new : self.source.response_headers
72
+ end
61
73
 
62
- def ==(other_source_file)
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
- private
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
- # A null source file is used to represent source that either doesn't exist
84
- # or source that is a proxy (ie a combination)
89
+ def slash_path(path)
90
+ File.join(path, "")
91
+ end
85
92
 
86
- class NullSourceFile < SourceFile
93
+ def read_file(path)
94
+ File.send(File.respond_to?(:binread) ? :binread : :read, path.to_s)
95
+ end
96
+ end
87
97
 
88
- def initialize(digest_path, options = nil)
89
- @file_path, @ext_list = '', []
90
- @digest_path = digest_path
91
- @source_proxy = if Dassets.config.combination?(@digest_path)
92
- SourceProxy.new(@digest_path, options)
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
- end
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
- def ==(other_source_file)
103
- self.file_path == other_source_file.file_path
104
- end
113
+ def compiled
114
+ @source_proxy.content
115
+ end
105
116
 
106
- class NullSourceProxy
107
- def content; nil; end
108
- def exists?; false; end
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
@@ -1,22 +1,25 @@
1
- require 'digest/md5'
2
- require 'dassets/cache'
3
- require 'dassets/source_file'
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 = nil)
12
- options ||= {}
13
+ def initialize(digest_path, **options)
13
14
  @digest_path = digest_path
14
- @content_cache = options[:content_cache] || Dassets::Cache::NoCache.new
15
- @fingerprint_cache = options[:fingerprint_cache] || Dassets::Cache::NoCache.new
16
- @source_files = get_source_files(@digest_path, {
17
- :content_cache => @content_cache,
18
- :fingerprint_cache => @fingerprint_cache
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 do |source_digest_path|
58
- Dassets::SourceFile.find_by_digest_path(source_digest_path, options)
59
- end
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
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Dassets
2
- VERSION = "0.14.1"
4
+ VERSION = "0.15.0"
3
5
  end
@@ -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 'pry'
8
+ require "pry"
9
9
 
10
- require 'test/support/factory'
10
+ require "test/support/factory"
11
11
 
12
- # 1.8.7 backfills
12
+ require "pathname"
13
+ TEST_SUPPORT_PATH = Pathname.new(File.expand_path("../support", __FILE__))
13
14
 
14
- # Array#sample
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 'pathname'
22
- TEST_SUPPORT_PATH = Pathname.new(File.expand_path('../support', __FILE__))
17
+ require "dassets"
23
18
 
24
- ENV['DASSETS_TEST_MODE'] = 'yes'
25
-
26
- require 'dassets'
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
- @dumb_engine = Class.new(Dassets::Engine) do
29
- def ext(in_ext); ''; end
30
- def compile(input); "#{input}\nDUMB"; end
31
- end
32
- @useless_engine = Class.new(Dassets::Engine) do
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 'dumb', @dumb_engine
40
- s.engine 'useless', @useless_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
@@ -1,10 +1,8 @@
1
- require 'sinatra/base'
1
+ require "sinatra/base"
2
2
 
3
3
  class SinatraApp < Sinatra::Base
4
-
5
4
  configure do
6
- set :root, File.expand_path('..', __FILE__)
7
- set :public_dir, File.expand_path('./app_public', __FILE__)
5
+ set :root, File.expand_path("..", __FILE__)
6
+ set :public_dir, File.expand_path("./app_public", __FILE__)
8
7
  end
9
-
10
8
  end
@@ -1,4 +1,4 @@
1
- require 'assert/factory'
1
+ require "assert/factory"
2
2
 
3
3
  module Factory
4
4
  extend Assert::Factory
@@ -6,5 +6,4 @@ module Factory
6
6
  def self.base_url
7
7
  Factory.boolean ? Factory.url : nil
8
8
  end
9
-
10
9
  end
@@ -0,0 +1 @@
1
+ ../linked_source_files/
@@ -0,0 +1 @@
1
+ ../linked_source_files/linked_file.txt
@@ -1,13 +1,12 @@
1
- require 'assert'
2
- require 'dassets'
1
+ require "assert"
2
+ require "dassets"
3
3
 
4
- require 'assert-rack-test'
5
- require 'fileutils'
6
- require 'dassets/server'
7
- require 'test/support/app'
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 '/file1-daa05c683a4913b268653f7a7e36a5b4.txt'
30
- assert_equal 200, resp.status
31
- assert_equal Dassets['file1.txt'].content, resp.body
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 '/file2-9bbe1047cffbb590f59e0e5aeff46ae4.txt'
36
- assert_equal 200, resp.status
37
- assert_equal Dassets['file2.txt'].size.to_s, resp.headers['Content-Length']
38
- assert_empty resp.body
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['file1.txt'].content
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 = { 'HTTP_RANGE' => "bytes=0-#{size}" }
46
+ env = { "HTTP_RANGE" => "bytes=0-#{size}" }
47
+ resp = get "/file1-daa05c683a4913b268653f7a7e36a5b4.txt", {}, env
47
48
 
48
- resp = get '/file1-daa05c683a4913b268653f7a7e36a5b4.txt', {}, env
49
- assert_equal 206, resp.status
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 = { 'HTTP_RANGE' => 'bytes=' }
55
+ env = { "HTTP_RANGE" => "bytes=" }
56
+ resp = get "/file1-daa05c683a4913b268653f7a7e36a5b4.txt", {}, env
56
57
 
57
- resp = get '/file1-daa05c683a4913b268653f7a7e36a5b4.txt', {}, env
58
- assert_equal 200, resp.status
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 = { 'HTTP_RANGE' => 'bytes=0-1,2-3' }
64
+ env = { "HTTP_RANGE" => "bytes=0-1,2-3" }
65
+ resp = get "/file1-daa05c683a4913b268653f7a7e36a5b4.txt", {}, env
65
66
 
66
- resp = get '/file1-daa05c683a4913b268653f7a7e36a5b4.txt', {}, env
67
- assert_equal 200, resp.status
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 = { 'HTTP_RANGE' => ['bytes=3-2', 'bytes=abc'].sample }
73
+ env = { "HTTP_RANGE" => ["bytes=3-2", "bytes=abc"].sample }
74
+ resp = get "/file1-daa05c683a4913b268653f7a7e36a5b4.txt", {}, env
74
75
 
75
- resp = get '/file1-daa05c683a4913b268653f7a7e36a5b4.txt', {}, env
76
- assert_equal 200, resp.status
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('public').to_s
87
- @url = Dassets['file1.txt'].url
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 FileStore::NullStore.new
92
+ Dassets.config.file_store Dassets::NullFileStore.new
93
93
  end
94
94
 
95
95
  should "digest the asset" do
96
- assert_not_file_exists @url_file
96
+ assert_that(@url_file).is_not_a_file
97
97
 
98
98
  resp = get @url
99
- assert_equal 200, resp.status
100
- assert_file_exists @url_file
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
- assert_equal 304, @resp.status
115
- assert_empty @resp.body
116
- end
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 '/file1-daa05c683a4913b268.txt'
125
- assert_equal 404, resp.status
122
+ resp = get "/file1-daa05c683a4913b268.txt"
123
+ assert_that(resp.status).equals(404)
126
124
 
127
- get '/file1-.txt'
128
- assert_equal 404, resp.status
125
+ resp = get "/file1-.txt"
126
+ assert_that(resp.status).equals(404)
129
127
 
130
- get '/file1.txt'
131
- assert_equal 404, resp.status
128
+ resp = get "/file1.txt"
129
+ assert_that(resp.status).equals(404)
132
130
 
133
- get '/something-not-found'
134
- assert_equal 404, resp.status
131
+ resp = get "/something-not-found"
132
+ assert_that(resp.status).equals(404)
135
133
  end
136
-
137
134
  end
138
-
139
135
  end