Skip to content

Commit 08f937a

Browse files
Refactor helper spec to utilize Async::Queue for improved chunk processing
1 parent 1df6176 commit 08f937a

File tree

1 file changed

+37
-10
lines changed

1 file changed

+37
-10
lines changed

spec/dummy/spec/helpers/react_on_rails_pro_helper_spec.rb

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# frozen_string_literal: true
22

3+
require "async"
4+
require "async/queue"
35
require "rails_helper"
46
require "support/script_tag_utils"
57

@@ -327,6 +329,7 @@ def response; end
327329
HTML
328330
end
329331

332+
# mock_chunks can be an Async::Queue or an Array
330333
def mock_request_and_response(mock_chunks = chunks, count: 1)
331334
# Reset connection instance variables to ensure clean state for tests
332335
ReactOnRailsPro::Request.instance_variable_set(:@connection, nil)
@@ -339,9 +342,16 @@ def mock_request_and_response(mock_chunks = chunks, count: 1)
339342
chunks_read.clear
340343
mock_streaming_response(%r{http://localhost:3800/bundles/[a-f0-9]{32}-test/render/[a-f0-9]{32}}, 200,
341344
count: count) do |yielder|
342-
mock_chunks.each do |chunk|
343-
chunks_read << chunk
344-
yielder.call("#{chunk.to_json}\n")
345+
if mock_chunks.is_a?(Async::Queue)
346+
while (chunk = mock_chunks.dequeue)
347+
chunks_read << chunk
348+
yielder.call("#{chunk.to_json}\n")
349+
end
350+
else
351+
mock_chunks.each do |chunk|
352+
chunks_read << chunk
353+
yielder.call("#{chunk.to_json}\n")
354+
end
345355
end
346356
end
347357
end
@@ -428,18 +438,35 @@ def mock_request_and_response(mock_chunks = chunks, count: 1)
428438

429439
allow(mocked_stream).to receive(:write) do |chunk|
430440
written_chunks << chunk
431-
# Ensures that any chunk received is written immediately to the stream
432-
expect(written_chunks.count).to eq(chunks_read.count) # rubocop:disable RSpec/ExpectInHook
433441
end
434442
allow(mocked_stream).to receive(:close)
435443
mocked_response = instance_double(ActionDispatch::Response)
436444
allow(mocked_response).to receive(:stream).and_return(mocked_stream)
437445
allow(self).to receive(:response).and_return(mocked_response)
438-
mock_request_and_response
446+
end
447+
448+
def execute_stream_view_containing_react_components
449+
queue = Async::Queue.new
450+
mock_request_and_response(queue)
451+
452+
Sync do |parent|
453+
parent.async { stream_view_containing_react_components(template: template_path) }
454+
455+
chunks_to_write = chunks.dup
456+
while (chunk = chunks_to_write.shift)
457+
queue.enqueue(chunk)
458+
sleep 0.05
459+
460+
# Ensures that any chunk received is written immediately to the stream
461+
expect(written_chunks.count).to eq(chunks_read.count)
462+
end
463+
queue.close
464+
sleep 0.05
465+
end
439466
end
440467

441468
it "writes the chunk to stream as soon as it is received" do
442-
stream_view_containing_react_components(template: template_path)
469+
execute_stream_view_containing_react_components
443470
expect(self).to have_received(:render_to_string).once.with(template: template_path)
444471
expect(chunks_read.count).to eq(chunks.count)
445472
expect(written_chunks.count).to eq(chunks.count)
@@ -448,7 +475,7 @@ def mock_request_and_response(mock_chunks = chunks, count: 1)
448475
end
449476

450477
it "prepends the rails context to the first chunk only" do
451-
stream_view_containing_react_components(template: template_path)
478+
execute_stream_view_containing_react_components
452479
initial_result = written_chunks.first
453480
expect(initial_result).to script_tag_be_included(rails_context_tag)
454481

@@ -464,7 +491,7 @@ def mock_request_and_response(mock_chunks = chunks, count: 1)
464491
end
465492

466493
it "prepends the component specification tag to the first chunk only" do
467-
stream_view_containing_react_components(template: template_path)
494+
execute_stream_view_containing_react_components
468495
initial_result = written_chunks.first
469496
expect(initial_result).to script_tag_be_included(react_component_specification_tag)
470497

@@ -475,7 +502,7 @@ def mock_request_and_response(mock_chunks = chunks, count: 1)
475502
end
476503

477504
it "renders the rails view content in the first chunk" do
478-
stream_view_containing_react_components(template: template_path)
505+
execute_stream_view_containing_react_components
479506
initial_result = written_chunks.first
480507
expect(initial_result).to include("<h1>Header Rendered In View</h1>")
481508
written_chunks[1..].each do |chunk|

0 commit comments

Comments
 (0)