Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 9 additions & 94 deletions core/io/buffer/external_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,103 +6,18 @@
@buffer = nil
end

context "with a buffer created with .new" do
it "is false for an internal buffer" do
@buffer = IO::Buffer.new(4)
@buffer.external?.should be_false
end

it "is false for a mapped buffer" do
@buffer = IO::Buffer.new(4, IO::Buffer::MAPPED)
@buffer.external?.should be_false
end
end

context "with a file-backed buffer created with .map" do
it "is true for a regular mapping" do
File.open(__FILE__, "r") do |file|
@buffer = IO::Buffer.map(file, nil, 0, IO::Buffer::READONLY)
@buffer.external?.should be_true
end
end

ruby_version_is "3.3" do
it "is false for a private mapping" do
File.open(__FILE__, "r") do |file|
@buffer = IO::Buffer.map(file, nil, 0, IO::Buffer::READONLY | IO::Buffer::PRIVATE)
@buffer.external?.should be_false
end
end
end
end

context "with a String-backed buffer created with .for" do
it "is true for a buffer created without a block" do
@buffer = IO::Buffer.for("test")
@buffer.external?.should be_true
end

it "is true for a buffer created with a block" do
IO::Buffer.for(+"test") do |buffer|
buffer.external?.should be_true
end
end
it "is true for a buffer with externally-managed memory" do
@buffer = IO::Buffer.for("string")
@buffer.external?.should be_true
end

ruby_version_is "3.3" do
context "with a String-backed buffer created with .string" do
it "is true" do
IO::Buffer.string(4) do |buffer|
buffer.external?.should be_true
end
end
end
it "is false for a buffer with self-managed memory" do
@buffer = IO::Buffer.new(12, IO::Buffer::MAPPED)
@buffer.external?.should be_false
end

# Always false for slices
context "with a slice of a buffer" do
context "created with .new" do
it "is false when slicing an internal buffer" do
@buffer = IO::Buffer.new(4)
@buffer.slice.external?.should be_false
end

it "is false when slicing a mapped buffer" do
@buffer = IO::Buffer.new(4, IO::Buffer::MAPPED)
@buffer.slice.external?.should be_false
end
end

context "created with .map" do
it "is false" do
File.open(__FILE__, "r") do |file|
@buffer = IO::Buffer.map(file, nil, 0, IO::Buffer::READONLY)
@buffer.slice.external?.should be_false
end
end
end

context "created with .for" do
it "is false when slicing a buffer created without a block" do
@buffer = IO::Buffer.for("test")
@buffer.slice.external?.should be_false
end

it "is false when slicing a buffer created with a block" do
IO::Buffer.for(+"test") do |buffer|
buffer.slice.external?.should be_false
end
end
end

ruby_version_is "3.3" do
context "created with .string" do
it "is false" do
IO::Buffer.string(4) do |buffer|
buffer.slice.external?.should be_false
end
end
end
end
it "is false for a null buffer" do
@buffer = IO::Buffer.new(0)
@buffer.external?.should be_false
end
end
115 changes: 115 additions & 0 deletions core/io/buffer/for_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
require_relative '../../../spec_helper'

describe "IO::Buffer.for" do
before :each do
@string = +"för striñg"
end

after :each do
@buffer&.free
@buffer = nil
end

context "without a block" do
it "copies string's contents, creating a separate read-only buffer" do
@buffer = IO::Buffer.for(@string)

@buffer.size.should == @string.bytesize
@buffer.get_string.should == @string.b

@string[0] = "d"
@buffer.get_string(0, 1).should == "f".b

-> { @buffer.set_string("d") }.should raise_error(IO::Buffer::AccessError, "Buffer is not writable!")
end

ruby_version_is ""..."3.3" do
it "creates an external, read-only buffer" do
@buffer = IO::Buffer.for(@string)

@buffer.should_not.internal?
@buffer.should_not.mapped?
@buffer.should.external?

@buffer.should_not.empty?
@buffer.should_not.null?

@buffer.should_not.shared?
@buffer.should.readonly?

@buffer.should_not.locked?
@buffer.should.valid?
end
end

ruby_version_is "3.3" do
it "creates an external, read-only buffer" do
@buffer = IO::Buffer.for(@string)

@buffer.should_not.internal?
@buffer.should_not.mapped?
@buffer.should.external?

@buffer.should_not.empty?
@buffer.should_not.null?

@buffer.should_not.shared?
@buffer.should_not.private?
@buffer.should.readonly?

@buffer.should_not.locked?
@buffer.should.valid?
end
end
end

context "with a block" do
it "returns the last value in the block" do
value =
IO::Buffer.for(@string) do |buffer|
buffer.size * 3
end
value.should == @string.bytesize * 3
end

it "frees the buffer at the end of the block" do
IO::Buffer.for(@string) do |buffer|
@buffer = buffer
@buffer.should_not.null?
end
@buffer.should.null?
end

context "if string is not frozen" do
it "creates a modifiable string-backed buffer" do
IO::Buffer.for(@string) do |buffer|
buffer.size.should == @string.bytesize
buffer.get_string.should == @string.b

buffer.should_not.readonly?

buffer.set_string("ghost shell")
@string.should == "ghost shellg"
end
end

it "locks the original string to prevent modification" do
IO::Buffer.for(@string) do |_buffer|
-> { @string[0] = "t" }.should raise_error(RuntimeError, "can't modify string; temporarily locked")
end
@string[1] = "u"
@string.should == "fur striñg"
end
end

context "if string is frozen" do
it "creates a read-only string-backed buffer" do
IO::Buffer.for(@string.freeze) do |buffer|
buffer.should.readonly?

-> { buffer.set_string("ghost shell") }.should raise_error(IO::Buffer::AccessError, "Buffer is not writable!")
end
end
end
end
end
69 changes: 56 additions & 13 deletions core/io/buffer/initialize_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,42 +12,62 @@
@buffer.each(:U8).should.all? { |_offset, value| value.eql?(0) }
end

it "creates a buffer with default state" do
@buffer = IO::Buffer.new
@buffer.should_not.shared?
@buffer.should_not.readonly?
ruby_version_is ""..."3.3" do
it "creates a buffer with default state" do
@buffer = IO::Buffer.new

@buffer.should_not.shared?
@buffer.should_not.readonly?

@buffer.should_not.empty?
@buffer.should_not.null?

@buffer.should_not.locked?
@buffer.should.valid?
end
end

ruby_version_is "3.3" do
it "creates a buffer with default state" do
@buffer = IO::Buffer.new

@buffer.should_not.empty?
@buffer.should_not.null?
@buffer.should_not.external?

# This is run-time state, set by #locked.
@buffer.should_not.locked?
@buffer.should_not.shared?
@buffer.should_not.private?
@buffer.should_not.readonly?

@buffer.should_not.empty?
@buffer.should_not.null?

@buffer.should_not.locked?
@buffer.should.valid?
end
end

context "with size argument" do
it "creates a new internal buffer if size is less than IO::Buffer::PAGE_SIZE" do
size = IO::Buffer::PAGE_SIZE - 1
@buffer = IO::Buffer.new(size)
@buffer.size.should == size
@buffer.should_not.empty?

@buffer.should.internal?
@buffer.should_not.mapped?
@buffer.should_not.empty?
end

it "creates a new mapped buffer if size is greater than or equal to IO::Buffer::PAGE_SIZE" do
size = IO::Buffer::PAGE_SIZE
@buffer = IO::Buffer.new(size)
@buffer.size.should == size
@buffer.should_not.empty?

@buffer.should_not.internal?
@buffer.should.mapped?
@buffer.should_not.empty?
end

it "creates a null buffer if size is 0" do
@buffer = IO::Buffer.new(0)
@buffer.size.should.zero?
@buffer.should_not.internal?
@buffer.should_not.mapped?
@buffer.should.null?
@buffer.should.empty?
end
Expand Down Expand Up @@ -77,6 +97,29 @@
@buffer.should_not.empty?
end

it "allows extra flags" do
@buffer = IO::Buffer.new(10, IO::Buffer::INTERNAL | IO::Buffer::SHARED | IO::Buffer::READONLY)
@buffer.should.internal?
@buffer.should.shared?
@buffer.should.readonly?
end

it "ignores flags if size is 0" do
@buffer = IO::Buffer.new(0, 0xffff)
@buffer.should.null?
@buffer.should.empty?

@buffer.should_not.internal?
@buffer.should_not.mapped?
@buffer.should_not.external?

@buffer.should_not.shared?
@buffer.should_not.readonly?

@buffer.should_not.locked?
@buffer.should.valid?
end

it "raises IO::Buffer::AllocationError if neither IO::Buffer::MAPPED nor IO::Buffer::INTERNAL is given" do
-> { IO::Buffer.new(10, IO::Buffer::READONLY) }.should raise_error(IO::Buffer::AllocationError, "Could not allocate buffer!")
-> { IO::Buffer.new(10, 0) }.should raise_error(IO::Buffer::AllocationError, "Could not allocate buffer!")
Expand Down
Loading