Skip to content

Commit 0873877

Browse files
andrykonchineregon
authored andcommitted
1 parent ba246c5 commit 0873877

11 files changed

Lines changed: 290 additions & 0 deletions

File tree

spec/ruby/core/data/fixtures/classes.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,12 @@ def initialize(amount:, unit:)
1717
end
1818

1919
Empty = Data.define()
20+
21+
DataWithOverriddenInitialize = Data.define(:amount, :unit) do
22+
def initialize(*rest, **kw)
23+
super
24+
ScratchPad.record [:initialize, rest, kw]
25+
end
26+
end
2027
end
2128
end

spec/ruby/core/data/initialize_spec.rb

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,4 +71,44 @@
7171
it "supports Data with no fields" do
7272
-> { DataSpecs::Empty.new }.should_not raise_error
7373
end
74+
75+
it "can be overridden" do
76+
ScratchPad.record []
77+
78+
measure_class = Data.define(:amount, :unit) do
79+
def initialize(*, **)
80+
super
81+
ScratchPad << :initialize
82+
end
83+
end
84+
85+
measure_class.new(42, "m")
86+
ScratchPad.recorded.should == [:initialize]
87+
end
88+
89+
context "when it is overridden" do
90+
it "is called with keyword arguments when given positional arguments" do
91+
ScratchPad.clear
92+
DataSpecs::DataWithOverriddenInitialize.new(42, "m")
93+
ScratchPad.recorded.should == [:initialize, [], {amount: 42, unit: "m"}]
94+
end
95+
96+
it "is called with keyword arguments when given keyword arguments" do
97+
ScratchPad.clear
98+
DataSpecs::DataWithOverriddenInitialize.new(amount: 42, unit: "m")
99+
ScratchPad.recorded.should == [:initialize, [], {amount: 42, unit: "m"}]
100+
end
101+
102+
it "is called with keyword arguments when given alternative positional arguments" do
103+
ScratchPad.clear
104+
DataSpecs::DataWithOverriddenInitialize[42, "m"]
105+
ScratchPad.recorded.should == [:initialize, [], {amount: 42, unit: "m"}]
106+
end
107+
108+
it "is called with keyword arguments when given alternative keyword arguments" do
109+
ScratchPad.clear
110+
DataSpecs::DataWithOverriddenInitialize[amount: 42, unit: "m"]
111+
ScratchPad.recorded.should == [:initialize, [], {amount: 42, unit: "m"}]
112+
end
113+
end
74114
end

spec/ruby/core/data/with_spec.rb

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,28 @@
3030
data.with(4, "m")
3131
}.should raise_error(ArgumentError, "wrong number of arguments (given 2, expected 0)")
3232
end
33+
34+
it "does not depend on the Data.new method" do
35+
subclass = Class.new(DataSpecs::Measure)
36+
data = subclass.new(amount: 42, unit: "km")
37+
38+
def subclass.new(*)
39+
raise "Data.new is called"
40+
end
41+
42+
data_copy = data.with(unit: "m")
43+
data_copy.amount.should == 42
44+
data_copy.unit.should == "m"
45+
end
46+
47+
ruby_version_is "3.3" do
48+
it "calls #initialize" do
49+
data = DataSpecs::DataWithOverriddenInitialize.new(42, "m")
50+
ScratchPad.clear
51+
52+
data.with(amount: 0)
53+
54+
ScratchPad.recorded.should == [:initialize, [], {amount: 0, unit: "m"}]
55+
end
56+
end
3357
end

spec/ruby/core/enumerable/fixtures/classes.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,14 @@ def each(*arg)
3838
class Empty
3939
include Enumerable
4040
def each
41+
self
4142
end
4243
end
4344

4445
class EmptyWithSize
4546
include Enumerable
4647
def each
48+
self
4749
end
4850
def size
4951
0

spec/ruby/core/exception/full_message_spec.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,4 +211,16 @@ class << e
211211
e.full_message(highlight: false).lines.first.should =~ /RuntimeError/
212212
e.full_message(highlight: true).lines.first.should =~ /#{Regexp.escape("\e[1;4mRuntimeError\e[m")}/
213213
end
214+
215+
it "allows cause with empty backtrace" do
216+
begin
217+
raise RuntimeError.new("Some runtime error"), cause: RuntimeError.new("Some other runtime error")
218+
rescue => e
219+
end
220+
221+
full_message = e.full_message
222+
full_message.should include "RuntimeError"
223+
full_message.should include "Some runtime error"
224+
full_message.should include "Some other runtime error"
225+
end
214226
end

spec/ruby/core/io/popen_spec.rb

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,22 @@
9595
@io = IO.popen(ruby_cmd('exit 0'), mode)
9696
end
9797

98+
it "accepts a path using the chdir: keyword argument" do
99+
path = File.dirname(@fname)
100+
101+
@io = IO.popen(ruby_cmd("puts Dir.pwd"), "r", chdir: path)
102+
@io.read.chomp.should == path
103+
end
104+
105+
it "accepts a path using the chdir: keyword argument and a coercible path" do
106+
path = File.dirname(@fname)
107+
object = mock("path")
108+
object.should_receive(:to_path).and_return(path)
109+
110+
@io = IO.popen(ruby_cmd("puts Dir.pwd"), "r", chdir: object)
111+
@io.read.chomp.should == path
112+
end
113+
98114
describe "with a block" do
99115
it "yields an open IO to the block" do
100116
IO.popen(ruby_cmd('exit'), "r") do |io|

spec/ruby/core/kernel/raise_spec.rb

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,84 @@
203203
e.cause.should == e1
204204
end
205205
end
206+
207+
it "re-raises a previously rescued exception that doesn't have a cause and isn't a cause of any other exception with setting a cause implicitly" do
208+
begin
209+
begin
210+
raise "Error 1"
211+
rescue => e1
212+
begin
213+
raise "Error 2"
214+
rescue => e2
215+
raise "Error 3"
216+
end
217+
end
218+
rescue => e
219+
e.message.should == "Error 3"
220+
e.cause.should == e2
221+
end
222+
end
223+
224+
it "re-raises a previously rescued exception that doesn't have a cause and is a cause of other exception without setting a cause implicitly" do
225+
begin
226+
begin
227+
raise "Error 1"
228+
rescue => e1
229+
begin
230+
raise "Error 2"
231+
rescue => e2
232+
e1.cause.should == nil
233+
e2.cause.should == e1
234+
raise e1
235+
end
236+
end
237+
rescue => e
238+
e.should == e1
239+
e.cause.should == nil
240+
end
241+
end
242+
243+
it "re-raises a previously rescued exception that doesn't have a cause and is a cause of other exception (that wasn't raised explicitly) without setting a cause implicitly" do
244+
begin
245+
begin
246+
raise "Error 1"
247+
rescue => e1
248+
begin
249+
foo # raises NameError
250+
rescue => e2
251+
e1.cause.should == nil
252+
e2.cause.should == e1
253+
raise e1
254+
end
255+
end
256+
rescue => e
257+
e.should == e1
258+
e.cause.should == nil
259+
end
260+
end
261+
262+
it "re-raises a previously rescued exception that has a cause but isn't a cause of any other exception without setting a cause implicitly" do
263+
begin
264+
begin
265+
raise "Error 1"
266+
rescue => e1
267+
begin
268+
raise "Error 2"
269+
rescue => e2
270+
begin
271+
raise "Error 3", cause: RuntimeError.new("Error 4")
272+
rescue => e3
273+
e2.cause.should == e1
274+
e3.cause.should_not == e2
275+
raise e2
276+
end
277+
end
278+
end
279+
rescue => e
280+
e.should == e2
281+
e.cause.should == e1
282+
end
283+
end
206284
end
207285

208286
describe "Kernel#raise" do

spec/ruby/language/assignments_spec.rb

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,37 @@ def object.[]=(_, _) end
4141
ScratchPad.recorded.should == [:rhs]
4242
end
4343
end
44+
45+
context "given block argument" do
46+
before do
47+
@klass = Class.new do
48+
def initialize(h) @h = h end
49+
def [](k, &block) @h[k]; end
50+
def []=(k, v, &block) @h[k] = v; end
51+
end
52+
end
53+
54+
ruby_version_is ""..."3.4" do
55+
it "accepts block argument" do
56+
obj = @klass.new(a: 1)
57+
block = proc {}
58+
59+
eval "obj[:a, &block] = 2"
60+
eval("obj[:a, &block]").should == 2
61+
end
62+
end
63+
64+
ruby_version_is "3.4" do
65+
it "raises SyntaxError" do
66+
obj = @klass.new(a: 1)
67+
block = proc {}
68+
69+
-> {
70+
eval "obj[:a, &block] = 2"
71+
}.should raise_error(SyntaxError, /unexpected block arg given in index assignment|block arg given in index assignment/)
72+
end
73+
end
74+
end
4475
end
4576

4677
describe 'using +=' do
@@ -114,6 +145,37 @@ def []=(k, v) @a[k] = v; 42 end
114145
a.public_method(:k, 2).should == 2
115146
end
116147

148+
context "given block argument" do
149+
before do
150+
@klass = Class.new do
151+
def initialize(h) @h = h end
152+
def [](k, &block) @h[k]; end
153+
def []=(k, v, &block) @h[k] = v; end
154+
end
155+
end
156+
157+
ruby_version_is ""..."3.4" do
158+
it "accepts block argument" do
159+
obj = @klass.new(a: 1)
160+
block = proc {}
161+
162+
eval "obj[:a, &block] += 2"
163+
eval("obj[:a, &block]").should == 3
164+
end
165+
end
166+
167+
ruby_version_is "3.4" do
168+
it "raises SyntaxError" do
169+
obj = @klass.new(a: 1)
170+
block = proc {}
171+
172+
-> {
173+
eval "obj[:a, &block] += 2"
174+
}.should raise_error(SyntaxError, /unexpected block arg given in index assignment|block arg given in index assignment/)
175+
end
176+
end
177+
end
178+
117179
context 'splatted argument' do
118180
it 'correctly handles it' do
119181
@b[:m] = 10

spec/ruby/language/hash_spec.rb

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,26 @@ def h.to_hash; {:b => 2, :c => 3}; end
149149
{a: 1, **h, c: 4}.should == {a: 1, b: 2, c: 4}
150150
end
151151

152+
ruby_version_is ""..."3.4" do
153+
it "does not expand nil using ** into {} and raises TypeError" do
154+
h = nil
155+
-> { {a: 1, **h} }.should raise_error(TypeError, "no implicit conversion of nil into Hash")
156+
157+
-> { {a: 1, **nil} }.should raise_error(TypeError, "no implicit conversion of nil into Hash")
158+
end
159+
end
160+
161+
ruby_version_is "3.4" do
162+
it "expands nil using ** into {}" do
163+
h = nil
164+
{**h}.should == {}
165+
{a: 1, **h}.should == {a: 1}
166+
167+
{**nil}.should == {}
168+
{a: 1, **nil}.should == {a: 1}
169+
end
170+
end
171+
152172
it "expands an '**{}' or '**obj' element with the last key/value pair taking precedence" do
153173
-> {
154174
@h = eval "{a: 1, **{a: 2, b: 3, c: 1}, c: 3}"

spec/ruby/language/method_spec.rb

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1175,6 +1175,31 @@ def m(a = nil, b = {}, v: false)
11751175
end
11761176
end
11771177

1178+
context "when passing **nil into a method that accepts keyword arguments" do
1179+
ruby_version_is ""..."3.4" do
1180+
it "raises TypeError" do
1181+
def m(**kw) kw; end
1182+
1183+
h = nil
1184+
-> { m(a: 1, **h) }.should raise_error(TypeError, "no implicit conversion of nil into Hash")
1185+
-> { m(a: 1, **nil) }.should raise_error(TypeError, "no implicit conversion of nil into Hash")
1186+
end
1187+
end
1188+
1189+
ruby_version_is "3.4" do
1190+
it "expands nil using ** into {}" do
1191+
def m(**kw) kw; end
1192+
1193+
h = nil
1194+
m(**h).should == {}
1195+
m(a: 1, **h).should == {a: 1}
1196+
1197+
m(**nil).should == {}
1198+
m(a: 1, **nil).should == {a: 1}
1199+
end
1200+
end
1201+
end
1202+
11781203
describe "A method call with a space between method name and parentheses" do
11791204
before(:each) do
11801205
def m(*args)

0 commit comments

Comments
 (0)