Skip to content

Commit cee62c6

Browse files
andrykonchineregon
authored andcommitted
1 parent d7af8af commit cee62c6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+886
-170
lines changed

spec/ruby/CONTRIBUTING.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -277,13 +277,13 @@ describe :kernel_sprintf, shared: true do
277277
end
278278

279279
describe "Kernel#sprintf" do
280-
it_behaves_like :kernel_sprintf, -> (format, *args) {
280+
it_behaves_like :kernel_sprintf, -> format, *args {
281281
sprintf(format, *args)
282282
}
283283
end
284284

285285
describe "Kernel.sprintf" do
286-
it_behaves_like :kernel_sprintf, -> (format, *args) {
286+
it_behaves_like :kernel_sprintf, -> format, *args {
287287
Kernel.sprintf(format, *args)
288288
}
289289
end

spec/ruby/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ More precisely, every latest stable MRI release should [pass](https://github.com
3535

3636
### Synchronization with Ruby Implementations
3737

38-
The specs are synchronized both ways around once a month by @eregon between ruby/spec, MRI, JRuby and TruffleRuby,
38+
The specs are synchronized both ways around once a month by @andrykonchin between ruby/spec, MRI, JRuby and TruffleRuby,
3939
using [this script](https://github.com/ruby/mspec/blob/master/tool/sync/sync-rubyspec.rb).
4040
Each of these repositories has a full copy of the specs under `spec/ruby` to ease editing specs.
4141
Any of these repositories can be used to add or edit specs, use what is most convenient for you.

spec/ruby/core/array/each_spec.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
# Mutating the array while it is being iterated is discouraged as it can result in confusing behavior.
88
# Yet a Ruby implementation must not crash in such a case, and following the simple CRuby behavior makes sense.
99
# CRuby simply reads the array storage and checks the size for every iteration;
10-
# like `i = 0; while i < size; yield self[i]; end`
10+
# like `i = 0; while i < size; yield self[i]; i += 1; end`
1111

1212
describe "Array#each" do
1313
it "yields each element to the block" do

spec/ruby/core/array/plus_spec.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
([1, 2, 3] + obj).should == [1, 2, 3, "x", "y"]
2222
end
2323

24-
it "raises a Typeerror if the given argument can't be converted to an array" do
24+
it "raises a TypeError if the given argument can't be converted to an array" do
2525
-> { [1, 2, 3] + nil }.should raise_error(TypeError)
2626
-> { [1, 2, 3] + "abc" }.should raise_error(TypeError)
2727
end

spec/ruby/core/array/to_h_spec.rb

+6
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@
4545
[:a, :b].to_h { |k| [k, k.to_s] }.should == { a: 'a', b: 'b' }
4646
end
4747

48+
it "passes to a block each element as a single argument" do
49+
ScratchPad.record []
50+
[[:a, 1], [:b, 2]].to_h { |*args| ScratchPad << args; [args[0], args[1]] }
51+
ScratchPad.recorded.sort.should == [[[:a, 1]], [[:b, 2]]]
52+
end
53+
4854
it "raises ArgumentError if block returns longer or shorter array" do
4955
-> do
5056
[:a, :b].to_h { |k| [k, k.to_s, 1] }

spec/ruby/core/enumerable/shared/inject.rb

+36-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,23 @@
1616

1717
it "can take two argument" do
1818
EnumerableSpecs::Numerous.new(1, 2, 3).send(@method, 10, :-).should == 4
19+
EnumerableSpecs::Numerous.new(1, 2, 3).send(@method, 10, "-").should == 4
20+
21+
[1, 2, 3].send(@method, 10, :-).should == 4
22+
[1, 2, 3].send(@method, 10, "-").should == 4
23+
end
24+
25+
it "converts non-Symbol method name argument to String with #to_str if two arguments" do
26+
name = Object.new
27+
def name.to_str; "-"; end
28+
29+
EnumerableSpecs::Numerous.new(1, 2, 3).send(@method, 10, name).should == 4
30+
[1, 2, 3].send(@method, 10, name).should == 4
31+
end
32+
33+
it "raises TypeError when the second argument is not Symbol or String and it cannot be converted to String if two arguments" do
34+
-> { EnumerableSpecs::Numerous.new(1, 2, 3).send(@method, 10, Object.new) }.should raise_error(TypeError, /is not a symbol nor a string/)
35+
-> { [1, 2, 3].send(@method, 10, Object.new) }.should raise_error(TypeError, /is not a symbol nor a string/)
1936
end
2037

2138
it "ignores the block if two arguments" do
@@ -39,6 +56,25 @@
3956

4057
it "can take a symbol argument" do
4158
EnumerableSpecs::Numerous.new(10, 1, 2, 3).send(@method, :-).should == 4
59+
[10, 1, 2, 3].send(@method, :-).should == 4
60+
end
61+
62+
it "can take a String argument" do
63+
EnumerableSpecs::Numerous.new(10, 1, 2, 3).send(@method, "-").should == 4
64+
[10, 1, 2, 3].send(@method, "-").should == 4
65+
end
66+
67+
it "converts non-Symbol method name argument to String with #to_str" do
68+
name = Object.new
69+
def name.to_str; "-"; end
70+
71+
EnumerableSpecs::Numerous.new(10, 1, 2, 3).send(@method, name).should == 4
72+
[10, 1, 2, 3].send(@method, name).should == 4
73+
end
74+
75+
it "raises TypeError when passed not Symbol or String method name argument and it cannot be converted to String" do
76+
-> { EnumerableSpecs::Numerous.new(10, 1, 2, 3).send(@method, Object.new) }.should raise_error(TypeError, /is not a symbol nor a string/)
77+
-> { [10, 1, 2, 3].send(@method, Object.new) }.should raise_error(TypeError, /is not a symbol nor a string/)
4278
end
4379

4480
it "without argument takes a block with an accumulator (with first element as initial value) and the current element. Value of block becomes new accumulator" do
@@ -77,7 +113,6 @@
77113
EnumerableSpecs::EachDefiner.new('a','b','c').send(@method) {|result, i| i+result}.should == "cba"
78114
EnumerableSpecs::EachDefiner.new(3, 4, 5).send(@method) {|result, i| result*i}.should == 60
79115
EnumerableSpecs::EachDefiner.new([1], 2, 'a','b').send(@method){|r,i| r<<i}.should == [1, 2, 'a', 'b']
80-
81116
end
82117
83118
it "returns nil when fails(legacy rubycon)" do

spec/ruby/core/enumerable/to_h_spec.rb

+8
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,14 @@ def enum.each(*args)
5353
@enum.to_h { |k| [k, k.to_s] }.should == { a: 'a', b: 'b' }
5454
end
5555

56+
it "passes to a block each element as a single argument" do
57+
enum_of_arrays = EnumerableSpecs::EachDefiner.new([:a, 1], [:b, 2])
58+
59+
ScratchPad.record []
60+
enum_of_arrays.to_h { |*args| ScratchPad << args; [args[0], args[1]] }
61+
ScratchPad.recorded.sort.should == [[[:a, 1]], [[:b, 2]]]
62+
end
63+
5664
it "raises ArgumentError if block returns longer or shorter array" do
5765
-> do
5866
@enum.to_h { |k| [k, k.to_s, 1] }

spec/ruby/core/env/to_h_spec.rb

+12
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,18 @@
1818
ENV.to_h { |k, v| [k, v.upcase] }.should == { 'a' => "B", 'c' => "D" }
1919
end
2020

21+
it "passes to a block each pair's key and value as separate arguments" do
22+
ENV.replace("a" => "b", "c" => "d")
23+
24+
ScratchPad.record []
25+
ENV.to_h { |k, v| ScratchPad << [k, v]; [k, v] }
26+
ScratchPad.recorded.sort.should == [["a", "b"], ["c", "d"]]
27+
28+
ScratchPad.record []
29+
ENV.to_h { |*args| ScratchPad << args; [args[0], args[1]] }
30+
ScratchPad.recorded.sort.should == [["a", "b"], ["c", "d"]]
31+
end
32+
2133
it "does not require the array elements to be strings" do
2234
ENV.replace("a" => "b", "c" => "d")
2335
ENV.to_h { |k, v| [k.to_sym, v.to_sym] }.should == { :a => :b, :c => :d }

spec/ruby/core/exception/detailed_message_spec.rb

+18-9
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,6 @@ def exception.detailed_message(**)
1515
exception.full_message(highlight: false).should.include? "<prefix>new error<suffix>"
1616
end
1717

18-
it "accepts highlight keyword argument and adds escape control sequences" do
19-
RuntimeError.new("new error").detailed_message(highlight: true).should == "\e[1mnew error (\e[1;4mRuntimeError\e[m\e[1m)\e[m"
20-
end
21-
22-
it "allows and ignores other keyword arguments" do
23-
RuntimeError.new("new error").detailed_message(foo: true).should == "new error (RuntimeError)"
24-
end
25-
2618
it "returns just a message if exception class is anonymous" do
2719
Class.new(RuntimeError).new("message").detailed_message.should == "message"
2820
end
@@ -31,13 +23,30 @@ def exception.detailed_message(**)
3123
RuntimeError.new("").detailed_message.should == "unhandled exception"
3224
end
3325

34-
it "returns just class name for an instance of RuntimeError subclass with empty message" do
26+
it "returns just class name for an instance other than RuntimeError with empty message" do
3527
DetailedMessageSpec::C.new("").detailed_message.should == "DetailedMessageSpec::C"
28+
StandardError.new("").detailed_message.should == "StandardError"
3629
end
3730

3831
it "returns a generated class name for an instance of RuntimeError anonymous subclass with empty message" do
3932
klass = Class.new(RuntimeError)
4033
klass.new("").detailed_message.should =~ /\A#<Class:0x\h+>\z/
4134
end
35+
36+
it "accepts highlight keyword argument and adds escape control sequences" do
37+
RuntimeError.new("new error").detailed_message(highlight: true).should == "\e[1mnew error (\e[1;4mRuntimeError\e[m\e[1m)\e[m"
38+
end
39+
40+
it "accepts highlight keyword argument and adds escape control sequences for an instance of RuntimeError with empty message" do
41+
RuntimeError.new("").detailed_message(highlight: true).should == "\e[1;4munhandled exception\e[m"
42+
end
43+
44+
it "accepts highlight keyword argument and adds escape control sequences for an instance other than RuntimeError with empty message" do
45+
StandardError.new("").detailed_message(highlight: true).should == "\e[1;4mStandardError\e[m"
46+
end
47+
48+
it "allows and ignores other keyword arguments" do
49+
RuntimeError.new("new error").detailed_message(foo: true).should == "new error (RuntimeError)"
50+
end
4251
end
4352
end

spec/ruby/core/hash/replace_spec.rb

+65-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,70 @@
11
require_relative '../../spec_helper'
22
require_relative 'fixtures/classes'
3-
require_relative 'shared/replace'
43

54
describe "Hash#replace" do
6-
it_behaves_like :hash_replace, :replace
5+
it "replaces the contents of self with other" do
6+
h = { a: 1, b: 2 }
7+
h.replace(c: -1, d: -2).should equal(h)
8+
h.should == { c: -1, d: -2 }
9+
end
10+
11+
it "tries to convert the passed argument to a hash using #to_hash" do
12+
obj = mock('{1=>2,3=>4}')
13+
obj.should_receive(:to_hash).and_return({ 1 => 2, 3 => 4 })
14+
15+
h = {}
16+
h.replace(obj)
17+
h.should == { 1 => 2, 3 => 4 }
18+
end
19+
20+
it "calls to_hash on hash subclasses" do
21+
h = {}
22+
h.replace(HashSpecs::ToHashHash[1 => 2])
23+
h.should == { 1 => 2 }
24+
end
25+
26+
it "transfers the compare_by_identity flag" do
27+
hash_a = { a: 1 }
28+
hash_b = { b: 2 }
29+
hash_b.compare_by_identity
30+
hash_a.should_not.compare_by_identity?
31+
hash_a.replace(hash_b)
32+
hash_a.should.compare_by_identity?
33+
34+
hash_a = { a: 1 }
35+
hash_b = { b: 2 }
36+
hash_a.compare_by_identity
37+
hash_a.should.compare_by_identity?
38+
hash_a.replace(hash_b)
39+
hash_a.should_not.compare_by_identity?
40+
end
41+
42+
it "does not transfer default values" do
43+
hash_a = {}
44+
hash_b = Hash.new(5)
45+
hash_a.replace(hash_b)
46+
hash_a.default.should == 5
47+
48+
hash_a = {}
49+
hash_b = Hash.new { |h, k| k * 2 }
50+
hash_a.replace(hash_b)
51+
hash_a.default(5).should == 10
52+
53+
hash_a = Hash.new { |h, k| k * 5 }
54+
hash_b = Hash.new(-> { raise "Should not invoke lambda" })
55+
hash_a.replace(hash_b)
56+
hash_a.default.should == hash_b.default
57+
end
58+
59+
it "raises a FrozenError if called on a frozen instance that would not be modified" do
60+
-> do
61+
HashSpecs.frozen_hash.replace(HashSpecs.frozen_hash)
62+
end.should raise_error(FrozenError)
63+
end
64+
65+
it "raises a FrozenError if called on a frozen instance that is modified" do
66+
-> do
67+
HashSpecs.frozen_hash.replace(HashSpecs.empty_frozen_hash)
68+
end.should raise_error(FrozenError)
69+
end
770
end

spec/ruby/core/hash/shared/replace.rb

-51
This file was deleted.

spec/ruby/core/hash/to_h_spec.rb

+10
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,16 @@
3737
{ a: 1, b: 2 }.to_h { |k, v| [k.to_s, v*v]}.should == { "a" => 1, "b" => 4 }
3838
end
3939

40+
it "passes to a block each pair's key and value as separate arguments" do
41+
ScratchPad.record []
42+
{ a: 1, b: 2 }.to_h { |k, v| ScratchPad << [k, v]; [k, v] }
43+
ScratchPad.recorded.sort.should == [[:a, 1], [:b, 2]]
44+
45+
ScratchPad.record []
46+
{ a: 1, b: 2 }.to_h { |*args| ScratchPad << args; [args[0], args[1]] }
47+
ScratchPad.recorded.sort.should == [[:a, 1], [:b, 2]]
48+
end
49+
4050
it "raises ArgumentError if block returns longer or shorter array" do
4151
-> do
4252
{ a: 1, b: 2 }.to_h { |k, v| [k.to_s, v*v, 1] }

spec/ruby/core/integer/chr_spec.rb

+9-9
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@
1010
end
1111

1212
it "raises a RangeError is self is less than 0" do
13-
-> { -1.chr }.should raise_error(RangeError)
14-
-> { (-bignum_value).chr }.should raise_error(RangeError)
13+
-> { -1.chr }.should raise_error(RangeError, /-1 out of char range/)
14+
-> { (-bignum_value).chr }.should raise_error(RangeError, /bignum out of char range/)
1515
end
1616

1717
it "raises a RangeError if self is too large" do
18-
-> { 2206368128.chr(Encoding::UTF_8) }.should raise_error(RangeError)
18+
-> { 2206368128.chr(Encoding::UTF_8) }.should raise_error(RangeError, /2206368128 out of char range/)
1919
end
2020

2121
describe "when Encoding.default_internal is nil" do
@@ -48,8 +48,8 @@
4848
end
4949

5050
it "raises a RangeError is self is greater than 255" do
51-
-> { 256.chr }.should raise_error(RangeError)
52-
-> { bignum_value.chr }.should raise_error(RangeError)
51+
-> { 256.chr }.should raise_error(RangeError, /256 out of char range/)
52+
-> { bignum_value.chr }.should raise_error(RangeError, /bignum out of char range/)
5353
end
5454
end
5555

@@ -137,7 +137,7 @@
137137
[620, "TIS-620"]
138138
].each do |integer, encoding_name|
139139
Encoding.default_internal = Encoding.find(encoding_name)
140-
-> { integer.chr }.should raise_error(RangeError)
140+
-> { integer.chr }.should raise_error(RangeError, /(invalid codepoint|out of char range)/)
141141
end
142142
end
143143
end
@@ -165,12 +165,12 @@
165165

166166
# http://redmine.ruby-lang.org/issues/4869
167167
it "raises a RangeError is self is less than 0" do
168-
-> { -1.chr(Encoding::UTF_8) }.should raise_error(RangeError)
169-
-> { (-bignum_value).chr(Encoding::EUC_JP) }.should raise_error(RangeError)
168+
-> { -1.chr(Encoding::UTF_8) }.should raise_error(RangeError, /-1 out of char range/)
169+
-> { (-bignum_value).chr(Encoding::EUC_JP) }.should raise_error(RangeError, /bignum out of char range/)
170170
end
171171

172172
it "raises a RangeError if self is too large" do
173-
-> { 2206368128.chr(Encoding::UTF_8) }.should raise_error(RangeError)
173+
-> { 2206368128.chr(Encoding::UTF_8) }.should raise_error(RangeError, /2206368128 out of char range/)
174174
end
175175

176176
it "returns a String with the specified encoding" do

0 commit comments

Comments
 (0)