Refactor logic for updating temp files in tests

This commit is contained in:
syeopite 2025-06-03 17:07:51 -07:00
parent dc198546a0
commit 52865ff0a2
No known key found for this signature in database
GPG Key ID: A73C186DA3955A1A

View File

@ -42,11 +42,21 @@ end
# Makes and yields a temporary file with the given prefix # Makes and yields a temporary file with the given prefix
private def make_temporary_file(prefix, contents = nil, &) private def make_temporary_file(prefix, contents = nil, &)
tempfile = File.tempfile(prefix, "static_assets_handler_spec", dir: "spec/http_server/handlers/static_assets_handler") tempfile = File.tempfile(prefix, "static_assets_handler_spec", dir: "spec/http_server/handlers/static_assets_handler")
yield tempfile file_link = "/#{File.basename(tempfile.path)}"
yield tempfile, file_link
ensure ensure
tempfile.try &.delete tempfile.try &.delete
end end
# Changes the contents of the temporary file after yield
private def cycle_temporary_file_contents(temporary_file, initial, &)
temporary_file.rewind << initial
temporary_file.rewind.flush
yield
temporary_file.rewind << "something else"
temporary_file.rewind.flush
end
# Get relative file path to a file within the static_assets_handler folder # Get relative file path to a file within the static_assets_handler folder
macro get_file_path(basename) macro get_file_path(basename)
"spec/http_server/handlers/static_assets_handler/#{ {{basename}} }" "spec/http_server/handlers/static_assets_handler/#{ {{basename}} }"
@ -60,24 +70,19 @@ Spectator.describe StaticAssetsHandler do
end end
it "Can serve cached file" do it "Can serve cached file" do
make_temporary_file("cache_test") do |temporary_file| make_temporary_file("cache_test") do |temporary_file, file_link|
temporary_file.rewind << "foo" cycle_temporary_file_contents(temporary_file, "foo") do
temporary_file.flush expect(temporary_file.rewind.gets_to_end).to eq("foo")
expect(temporary_file.rewind.gets_to_end).to eq("foo")
file_link = "/#{File.basename(temporary_file.path)}" # Should get cached by the first run
response = handle HTTP::Request.new("GET", file_link)
expect(response.status_code).to eq(200)
expect(response.body).to eq("foo")
end
# Should get cached by the first run # Temporary file is updated after `cycle_temporary_file_contents` is called
response = handle HTTP::Request.new("GET", file_link) # but if the file is successfully cached then we'll only get the original
expect(response.status_code).to eq(200) # contents.
expect(response.body).to eq("foo")
# Update temporary file to "bar"
temporary_file.rewind << "bar"
temporary_file.flush
expect(temporary_file.rewind.gets_to_end).to eq("bar")
# Second request should still return "foo"
response = handle HTTP::Request.new("GET", file_link) response = handle HTTP::Request.new("GET", file_link)
expect(response.status_code).to eq(200) expect(response.status_code).to eq(200)
expect(response.body).to eq("foo") expect(response.body).to eq("foo")
@ -100,17 +105,10 @@ Spectator.describe StaticAssetsHandler do
end end
it "Will cache entire file even if doing partial requests" do it "Will cache entire file even if doing partial requests" do
make_temporary_file("range_cache") do |temporary_file| make_temporary_file("range_cache") do |temporary_file, file_link|
temporary_file << "Hello world" cycle_temporary_file_contents(temporary_file, "Hello world") do
temporary_file.flush.rewind handle HTTP::Request.new("GET", file_link, HTTP::Headers{"Range" => "bytes=0-2"})
file_link = "/#{File.basename(temporary_file.path)}" end
# Make request
handle HTTP::Request.new("GET", file_link, HTTP::Headers{"Range" => "bytes=0-2"})
# Mutate file on disk
temporary_file << "Something else"
temporary_file.flush.rewind
# Second request shouldn't have changed # Second request shouldn't have changed
headers = HTTP::Headers{"Range" => "bytes=3-8"} headers = HTTP::Headers{"Range" => "bytes=3-8"}
@ -134,19 +132,12 @@ Spectator.describe StaticAssetsHandler do
handler = HTTP::CompressHandler.new handler = HTTP::CompressHandler.new
handler.next = get_static_assets_handler() handler.next = get_static_assets_handler()
make_temporary_file("check decompression handler") do |temporary_file| make_temporary_file("check decompression handler") do |temporary_file, file_link|
temporary_file << "Hello world" cycle_temporary_file_contents(temporary_file, "Hello world") do
temporary_file.flush.rewind response = handle HTTP::Request.new("GET", file_link, headers: HTTP::Headers{"Accept-Encoding" => "gzip"}), handler: handler
file_link = "/#{File.basename(temporary_file.path)}" expect(response.headers["Content-Encoding"]).to eq("gzip")
decompressed(response.body).to eq("Hello world")
# Can send from disk? end
response = handle HTTP::Request.new("GET", file_link, headers: HTTP::Headers{"Accept-Encoding" => "gzip"}), handler: handler
expect(response.headers["Content-Encoding"]).to eq("gzip")
decompressed(response.body).to eq("Hello world")
temporary_file << "Hello world"
temporary_file.flush.rewind
file_link = "/#{File.basename(temporary_file.path)}"
# Are cached requests working? # Are cached requests working?
response = handle HTTP::Request.new("GET", file_link, headers: HTTP::Headers{"Accept-Encoding" => "gzip"}), handler: handler response = handle HTTP::Request.new("GET", file_link, headers: HTTP::Headers{"Accept-Encoding" => "gzip"}), handler: handler
@ -165,40 +156,38 @@ Spectator.describe StaticAssetsHandler do
handler = HTTP::CompressHandler.new handler = HTTP::CompressHandler.new
handler.next = get_static_assets_handler() handler.next = get_static_assets_handler()
make_temporary_file("check_decompression_handler_on_partial_requests") do |temporary_file| make_temporary_file("check_decompression_handler_on_partial_requests") do |temporary_file, file_link|
temporary_file << "Hello world this is a very long string" cycle_temporary_file_contents(temporary_file, "Hello world this is a very long string") do
temporary_file.flush.rewind range_response_results = {
file_link = "/#{File.basename(temporary_file.path)}" "10-20/38" => "d this is a",
"0-0/38" => "H",
"5-9/38" => " worl",
}
range_response_results = { range_request_header_value = {"10-20", "5-9", "0-0"}.join(',')
"10-20/38" => "d this is a", range_response_header_value = range_response_results.keys
"0-0/38" => "H",
"5-9/38" => " worl",
}
range_request_header_value = {"10-20", "5-9", "0-0"}.join(',') response = handle HTTP::Request.new("GET", file_link, headers: HTTP::Headers{"Range" => "bytes=#{range_request_header_value}", "Accept-Encoding" => "gzip"}), handler: handler
range_response_header_value = range_response_results.keys expect(response.headers["Content-Encoding"]).to eq("gzip")
response = handle HTTP::Request.new("GET", file_link, headers: HTTP::Headers{"Range" => "bytes=#{range_request_header_value}", "Accept-Encoding" => "gzip"}), handler: handler # Decompress response
expect(response.headers["Content-Encoding"]).to eq("gzip") response = HTTP::Client::Response.new(
status: response.status,
headers: response.headers,
body_io: Compress::Gzip::Reader.new(IO::Memory.new(response.body)),
)
# Decompress response count = 0
response = HTTP::Client::Response.new( MIME::Multipart.parse(response) do |headers, part|
status: response.status, part_range = headers["Content-Range"][6..]
headers: response.headers, expect(part_range).to be_within(range_response_header_value)
body_io: Compress::Gzip::Reader.new(IO::Memory.new(response.body)), expect(part.gets_to_end).to eq(range_response_results[part_range])
) count += 1
end
count = 0 expect(count).to eq(3)
MIME::Multipart.parse(response) do |headers, part|
part_range = headers["Content-Range"][6..]
expect(part_range).to be_within(range_response_header_value)
expect(part.gets_to_end).to eq(range_response_results[part_range])
count += 1
end end
expect(count).to eq(3)
# Is the file cached? # Is the file cached?
temporary_file << "Something else" temporary_file << "Something else"
temporary_file.flush.rewind temporary_file.flush.rewind