Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Marshal #1524

Merged
merged 2 commits into from
Sep 22, 2023
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
38 changes: 24 additions & 14 deletions core/marshal.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,16 @@
# which is Marshal.loaded in _load for complex objects.
#
module Marshal
# <!-- rdoc-file=marshal.c -->
# major version
#
MAJOR_VERSION: Integer

# <!-- rdoc-file=marshal.c -->
# minor version
#
MINOR_VERSION: Integer

# <!--
# rdoc-file=marshal.c
# - dump( obj [, anIO] , limit=-1 ) -> anIO
Expand Down Expand Up @@ -141,8 +151,8 @@ module Marshal
# ThreadGroup, Continuation
# * objects which define singleton methods
#
def self.dump: (untyped obj, untyped port, ?Integer limit) -> untyped
| (untyped obj, ?Integer limit) -> String
def self?.dump: [W < _Writer] (untyped obj, W port, ?int? limit) -> W
| (untyped obj, ?Integer limit) -> String

# <!--
# rdoc-file=marshal.rb
Expand Down Expand Up @@ -175,8 +185,18 @@ module Marshal
# deserialized.map(&:object_id)
# # => [1039360, 1039380, 1039360, 1039380] -- only 2 different objects, object_ids repeating
#
def self.load: (String | untyped port, ?freeze: boolish) -> untyped
| [A] (String | untyped port, ^(untyped) -> A, ?freeze: boolish) -> A
def self.load: (string | _Source source, ?freeze: boolish) -> untyped
| [A] (string | _Source source, _Proc[A] proc, ?freeze: boolish) -> A

interface _Proc[T]
def call: (untyped loaded) -> T
end

interface _Source
def getbyte: () -> (String | int)

def read: (Integer) -> string
end

# <!--
# rdoc-file=marshal.rb
Expand All @@ -185,13 +205,3 @@ module Marshal
#
alias self.restore self.load
end

# <!-- rdoc-file=marshal.c -->
# major version
#
Marshal::MAJOR_VERSION: Integer

# <!-- rdoc-file=marshal.c -->
# minor version
#
Marshal::MINOR_VERSION: Integer
120 changes: 87 additions & 33 deletions test/stdlib/Marshal_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,51 +6,105 @@ class MarshalSingletonTest < Test::Unit::TestCase
include TypeAssertions
testing "singleton(::Marshal)"

def test_MAJOR_VERSION
assert_const_type 'Integer', 'Marshal::MAJOR_VERSION'
end

def test_MINOR_VERSION
assert_const_type 'Integer', 'Marshal::MINOR_VERSION'
end

def test_dump
assert_send_type "(::String) -> ::String",
Marshal, :dump, ""
obj = Object.new

assert_send_type "(::String, ::Integer) -> ::String",
Marshal, :dump, "", 3
assert_send_type '(untyped) -> String',
Marshal, :dump, obj
assert_send_type '(untyped, Integer) -> String',
Marshal, :dump, obj, 123

io = (Pathname(Dir.mktmpdir) + "foo").open("w")
writer = Writer.new
assert_send_type '(untyped, Writer) -> Writer',
Marshal, :dump, obj, writer

assert_send_type "(::String, ::File) -> ::File",
Marshal, :dump, "", io
with_int.chain([nil]).each do |limit|
assert_send_type '(untyped, Writer, int?) -> Writer',
Marshal, :dump, obj, writer, limit
end
end

def test_load
dump = Marshal.dump([1,2,3])
def with_source(src = Marshal.dump(Object.new))
with_string src do |string|
def string.reset!; end
yield string
end

src = src.chars
source = Struct.new(:source).new(src.dup)
source.define_singleton_method(:reset!) do
self.source = src.dup
end

# String, String
def source.getbyte; source.shift end
def source.read(x) source.shift(x).join end
yield source

# int, string
source.reset!
def source.getbyte; ToInt.new(source.shift.ord) end
def source.read(x) ToStr.new(source.shift(x).join) end
yield source
end

assert_send_type(
"(::String) -> ::Array[::Integer]",
Marshal, :load, dump
)
def test_load(meth = :load)
result_proc = Object.new
def result_proc.call(loaded) 1r end

assert_send_type(
"(::String, freeze: bool) -> ::Array[::Integer]",
Marshal, :load, dump, freeze: true
)
assert_send_type(
"(::String, freeze: Symbol) -> ::Array[::Integer]",
Marshal, :load, dump, freeze: :true
)
with_source do |source|
assert_send_type '(string | Marshal::_Source) -> untyped',
Marshal, meth, source
source.reset!

assert_send_type(
"(::String, ^(untyped) -> void) -> ::Integer",
Marshal, :load, dump, -> (_x) { 123 }
)
assert_send_type '(string | Marshal::_Source, Marshal::_Proc[Rational]) -> Rational',
Marshal, meth, source, result_proc
source.reset!

name = Pathname(Dir.mktmpdir) + "foo"
[nil, :yep, true, "hello"].each do |freeze|
assert_send_type '(string | Marshal::_Source, freeze: boolish) -> untyped',
Marshal, meth, source, freeze: freeze
source.reset!

File.open(name, "w") do |io|
Marshal.dump([1,2,3], io)
assert_send_type '(string | Marshal::_Source, Marshal::_Proc[Rational], freeze: boolish) -> Rational',
Marshal, meth, source, result_proc, freeze: freeze
source.reset!
end
end
File.open(name) do |io|
assert_send_type(
"(IO) -> ::Array[::Integer]",
Marshal, :load, io
)
end

def test_restore
test_load :restore
end
end

class MarshalIncludeTest < Test::Unit::TestCase
include TypeAssertions
testing "::Marshal"

def test_dump
obj = Object.new

assert_send_type '(untyped) -> String',
Marshal, :dump, obj
assert_send_type '(untyped, Integer) -> String',
Marshal, :dump, obj, 123

writer = Writer.new
assert_send_type '(untyped, Writer) -> Writer',
Marshal, :dump, obj, writer

with_int.chain([nil]).each do |limit|
assert_send_type '(untyped, Writer, int?) -> Writer',
Marshal, :dump, obj, writer, limit
end
end
end
12 changes: 12 additions & 0 deletions test/stdlib/test_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,18 @@ def each(&block)
end
end

class Writer
attr_reader :buffer

def initialize
@buffer = ""
end

def write(*vals)
@buffer.concat vals.join
end
end

class ToJson
end

Expand Down