spec/async/io/stream_spec.rb in async-io-1.12.3 vs spec/async/io/stream_spec.rb in async-io-1.13.0

- old
+ new

@@ -17,16 +17,19 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. require 'async/io/stream' +require 'async/rspec/buffer' RSpec.describe Async::IO::Stream do + include_context Async::RSpec::Buffer include_context Async::RSpec::Memory + include_context Async::RSpec::Reactor - let(:io) {StringIO.new} - let(:stream) {Async::IO::Stream.new(io)} + let!(:stream) {Async::IO::Stream.new(buffer)} + let(:io) {stream.io} describe '#read' do it "should read everything" do io.write "Hello World" io.seek(0) @@ -49,16 +52,24 @@ expect(stream.read(20)).to be == "o World" expect(stream).to be_eof end context "with large content" do - let!(:io) { StringIO.new("a" * 5*1024*1024) } - it "allocates expected amount of bytes" do + io.write("." * 16*1024) + io.seek(0) + + buffer = nil + expect do - stream.read(16*1024).clear until stream.eof? - end.to limit_allocations(size: 100*1024) + # The read buffer is already allocated, and it will be resized to fit the incoming data. It will be swapped with an empty buffer. + buffer = stream.read(16*1024) + end.to limit_allocations.of(String, count: 1, size: 0) + + expect(buffer.size).to be == 16*1024 + + io.close end end end describe '#read_until' do @@ -70,16 +81,14 @@ expect(stream.read_until("\n")).to be == 'world' expect(stream.read_until("\n")).to be_nil end context "with large content" do - let!(:io) { StringIO.new("a" * 5*1024*1024 + "b") } - it "allocates expected amount of bytes" do expect do - stream.read_until("b").clear - end.to limit_allocations(size: 100*1024) + stream.read_until("b") + end.to limit_allocations.of(String, size: 0, count: 1) end end end describe '#flush' do @@ -97,26 +106,42 @@ end end end describe '#read_partial' do - it "should avoid calling read" do - io.write "Hello World" * 1024 + before(:each) do + io.write "Hello World!" * 1024 io.seek(0) - + end + + it "should avoid calling read" do expect(io).to receive(:read).and_call_original.once - expect(stream.read_partial(11)).to be == "Hello World" + expect(stream.read_partial(12)).to be == "Hello World!" end context "with large content" do - let!(:io) { StringIO.new("a" * 5*1024*1024) } + it "allocates only the amount required" do + expect do + stream.read(4*1024) + end.to limit_allocations.of(String, count: 2, size: 4*1024+1) + end + it "allocates exact number of bytes being read" do + expect do + stream.read(16*1024) + end.to limit_allocations.of(String, count: 1, size: 0) + end + it "allocates expected amount of bytes" do + buffer = nil + expect do - stream.read_partial(16*1024).clear until stream.eof? - end.to limit_allocations(size: 100*1024) + buffer = stream.read_partial + end.to limit_allocations.of(String, count: 1) + + expect(buffer.size).to be == stream.block_size end end end describe '#write' do @@ -124,10 +149,12 @@ expect(io).to receive(:write).and_call_original.once stream.write "Hello World\n" stream.flush - expect(io.string).to be == "Hello World\n" + io.seek(0) + + expect(stream.read).to be == "Hello World\n" end end describe '#eof' do it "should terminate stream" do