From 18b4def471bb901d0baa4a1307185484cb05815f Mon Sep 17 00:00:00 2001 From: Benoit Daloze Date: Mon, 27 Feb 2023 21:02:44 +0100 Subject: Update to ruby/spec@e7dc804 --- spec/ruby/core/array/all_spec.rb | 13 ++ spec/ruby/core/array/any_spec.rb | 12 ++ spec/ruby/core/array/count_spec.rb | 11 + spec/ruby/core/array/delete_if_spec.rb | 30 +++ spec/ruby/core/array/drop_while_spec.rb | 4 + spec/ruby/core/array/each_index_spec.rb | 16 ++ spec/ruby/core/array/each_spec.rb | 5 + spec/ruby/core/array/fill_spec.rb | 42 ++++ spec/ruby/core/array/initialize_spec.rb | 4 +- spec/ruby/core/array/intersect_spec.rb | 53 ++++- spec/ruby/core/array/new_spec.rb | 4 +- spec/ruby/core/array/none_spec.rb | 13 ++ spec/ruby/core/array/one_spec.rb | 13 ++ spec/ruby/core/array/reject_spec.rb | 15 ++ spec/ruby/core/array/reverse_each_spec.rb | 14 ++ spec/ruby/core/array/rindex_spec.rb | 15 ++ spec/ruby/core/array/shared/collect.rb | 32 +++ spec/ruby/core/array/shared/index.rb | 4 + spec/ruby/core/array/shared/intersection.rb | 3 +- .../iterable_and_tolerating_size_increasing.rb | 25 +++ spec/ruby/core/array/shared/keep_if.rb | 35 ++++ spec/ruby/core/array/shared/select.rb | 3 + spec/ruby/core/array/sort_by_spec.rb | 33 +++ spec/ruby/core/array/sum_spec.rb | 6 + spec/ruby/core/array/take_while_spec.rb | 6 + spec/ruby/core/array/to_h_spec.rb | 6 + spec/ruby/core/array/uniq_spec.rb | 34 +++ spec/ruby/core/basicobject/fixtures/classes.rb | 228 ++++++++++++++++++++- spec/ruby/core/basicobject/instance_eval_spec.rb | 117 +++++++++-- spec/ruby/core/basicobject/method_missing_spec.rb | 1 + spec/ruby/core/data/define_spec.rb | 26 +++ spec/ruby/core/data/fixtures/classes.rb | 5 + spec/ruby/core/data/initialize_spec.rb | 58 ++++++ .../destination_encoding_name_spec.rb | 1 + .../destination_encoding_spec.rb | 1 + .../error_bytes_spec.rb | 1 + .../readagain_bytes_spec.rb | 1 + .../source_encoding_name_spec.rb | 1 + .../source_encoding_spec.rb | 1 + spec/ruby/core/encoding/name_spec.rb | 1 + spec/ruby/core/encoding/to_s_spec.rb | 1 + .../destination_encoding_name_spec.rb | 1 + .../destination_encoding_spec.rb | 1 + .../undefined_conversion_error/error_char_spec.rb | 1 + .../source_encoding_name_spec.rb | 1 + .../source_encoding_spec.rb | 1 + spec/ruby/core/enumerable/all_spec.rb | 6 + spec/ruby/core/enumerable/any_spec.rb | 6 + spec/ruby/core/enumerable/chunk_spec.rb | 5 + spec/ruby/core/enumerable/none_spec.rb | 6 + spec/ruby/core/enumerable/one_spec.rb | 7 +- spec/ruby/core/enumerable/shared/inject.rb | 35 +++- spec/ruby/core/enumerator/chain/inspect_spec.rb | 4 + spec/ruby/core/enumerator/inspect_spec.rb | 5 + spec/ruby/core/enumerator/lazy/compact_spec.rb | 5 + .../core/exception/fixtures/thread_fiber_ensure.rb | 22 ++ .../fixtures/thread_fiber_ensure_non_root_fiber.rb | 25 +++ spec/ruby/core/exception/top_level_spec.rb | 12 ++ spec/ruby/core/file/new_spec.rb | 59 +++++- spec/ruby/core/file/open_spec.rb | 11 + spec/ruby/core/float/magnitude_spec.rb | 1 + spec/ruby/core/io/initialize_spec.rb | 13 ++ spec/ruby/core/io/read_spec.rb | 36 ++++ spec/ruby/core/io/readlines_spec.rb | 6 + spec/ruby/core/io/shared/binwrite.rb | 15 ++ spec/ruby/core/io/shared/new.rb | 11 + spec/ruby/core/io/write_spec.rb | 91 +++++++- spec/ruby/core/kernel/Integer_spec.rb | 13 +- spec/ruby/core/kernel/at_exit_spec.rb | 61 +----- spec/ruby/core/kernel/exit_spec.rb | 10 +- spec/ruby/core/kernel/fixtures/at_exit.rb | 3 - spec/ruby/core/kernel/open_spec.rb | 25 ++- spec/ruby/core/kernel/singleton_class_spec.rb | 20 +- spec/ruby/core/marshal/shared/load.rb | 6 +- .../ruby/core/module/const_source_location_spec.rb | 7 +- spec/ruby/core/module/method_added_spec.rb | 73 ++++++- spec/ruby/core/numeric/magnitude_spec.rb | 1 + spec/ruby/core/process/exit_spec.rb | 2 +- spec/ruby/core/random/new_spec.rb | 1 + spec/ruby/core/range/step_spec.rb | 7 + spec/ruby/core/rational/abs_spec.rb | 1 + spec/ruby/core/rational/ceil_spec.rb | 1 + spec/ruby/core/rational/coerce_spec.rb | 1 + spec/ruby/core/rational/comparison_spec.rb | 1 + spec/ruby/core/rational/denominator_spec.rb | 1 + spec/ruby/core/rational/div_spec.rb | 1 + spec/ruby/core/rational/divide_spec.rb | 1 + spec/ruby/core/rational/divmod_spec.rb | 1 + spec/ruby/core/rational/equal_value_spec.rb | 1 + spec/ruby/core/rational/exponent_spec.rb | 1 + spec/ruby/core/rational/fdiv_spec.rb | 1 + spec/ruby/core/rational/floor_spec.rb | 1 + spec/ruby/core/rational/hash_spec.rb | 1 + spec/ruby/core/rational/inspect_spec.rb | 1 + spec/ruby/core/rational/integer_spec.rb | 1 + spec/ruby/core/rational/magnitude_spec.rb | 1 + spec/ruby/core/rational/modulo_spec.rb | 1 + spec/ruby/core/rational/multiply_spec.rb | 1 + spec/ruby/core/rational/numerator_spec.rb | 1 + spec/ruby/core/rational/plus_spec.rb | 1 + spec/ruby/core/rational/quo_spec.rb | 1 + spec/ruby/core/rational/remainder_spec.rb | 1 + spec/ruby/core/rational/to_f_spec.rb | 1 + spec/ruby/core/rational/to_i_spec.rb | 1 + spec/ruby/core/rational/to_r_spec.rb | 1 + spec/ruby/core/rational/to_s_spec.rb | 1 + spec/ruby/core/rational/truncate_spec.rb | 1 + spec/ruby/core/rational/zero_spec.rb | 1 + spec/ruby/core/string/casecmp_spec.rb | 10 + spec/ruby/core/string/chars_spec.rb | 1 + spec/ruby/core/string/each_char_spec.rb | 1 + .../ruby/core/string/each_grapheme_cluster_spec.rb | 1 + spec/ruby/core/string/grapheme_clusters_spec.rb | 1 + spec/ruby/core/string/shared/to_sym.rb | 2 +- spec/ruby/core/struct/deconstruct_keys_spec.rb | 2 +- spec/ruby/core/struct/initialize_spec.rb | 10 + spec/ruby/core/struct/inspect_spec.rb | 5 - spec/ruby/core/struct/shared/inspect.rb | 23 +++ spec/ruby/core/symbol/casecmp_spec.rb | 8 + spec/ruby/core/thread/kill_spec.rb | 4 - spec/ruby/core/thread/native_thread_id_spec.rb | 33 ++- spec/ruby/core/thread/shared/exit.rb | 19 ++ spec/ruby/core/time/succ_spec.rb | 3 +- spec/ruby/core/unboundmethod/bind_call_spec.rb | 8 + spec/ruby/core/unboundmethod/bind_spec.rb | 8 + spec/ruby/core/unboundmethod/fixtures/classes.rb | 4 + spec/ruby/fixtures/constants.rb | 3 +- spec/ruby/language/END_spec.rb | 26 ++- spec/ruby/language/fixtures/super.rb | 14 ++ spec/ruby/language/hash_spec.rb | 31 ++- spec/ruby/language/if_spec.rb | 43 ++++ .../ruby/language/regexp/character_classes_spec.rb | 4 +- spec/ruby/language/super_spec.rb | 4 + spec/ruby/language/symbol_spec.rb | 4 +- spec/ruby/library/date/strftime_spec.rb | 1 + .../delegate_class/respond_to_missing_spec.rb | 1 + spec/ruby/library/etc/confstr_spec.rb | 2 +- spec/ruby/library/etc/passwd_spec.rb | 2 +- spec/ruby/library/etc/sysconf_spec.rb | 2 +- spec/ruby/library/etc/sysconfdir_spec.rb | 2 +- spec/ruby/library/etc/systmpdir_spec.rb | 2 +- spec/ruby/library/expect/expect_spec.rb | 3 +- .../rubygems/gem/load_path_insert_index_spec.rb | 2 +- spec/ruby/library/set/comparison_spec.rb | 58 +++--- spec/ruby/library/set/each_spec.rb | 1 + spec/ruby/library/set/to_s_spec.rb | 1 + spec/ruby/library/socket/tcpsocket/open_spec.rb | 1 + .../library/win32ole/win32ole/_getproperty_spec.rb | 1 + .../ruby/library/win32ole/win32ole/_invoke_spec.rb | 1 + .../library/win32ole/win32ole/codepage_spec.rb | 1 + .../ruby/library/win32ole/win32ole/connect_spec.rb | 1 + .../library/win32ole/win32ole/const_load_spec.rb | 1 + .../library/win32ole/win32ole/constants_spec.rb | 1 + .../library/win32ole/win32ole/create_guid_spec.rb | 1 + spec/ruby/library/win32ole/win32ole/invoke_spec.rb | 1 + spec/ruby/library/win32ole/win32ole/locale_spec.rb | 1 + spec/ruby/library/win32ole/win32ole/new_spec.rb | 1 + .../win32ole/win32ole/ole_func_methods_spec.rb | 1 + .../win32ole/win32ole/ole_get_methods_spec.rb | 1 + .../win32ole/win32ole/ole_method_help_spec.rb | 1 + .../library/win32ole/win32ole/ole_method_spec.rb | 1 + .../library/win32ole/win32ole/ole_methods_spec.rb | 1 + .../library/win32ole/win32ole/ole_obj_help_spec.rb | 1 + .../win32ole/win32ole/ole_put_methods_spec.rb | 1 + .../library/win32ole/win32ole/setproperty_spec.rb | 1 + .../library/win32ole/win32ole_event/new_spec.rb | 1 + .../win32ole/win32ole_event/on_event_spec.rb | 1 + .../win32ole/win32ole_method/dispid_spec.rb | 1 + .../win32ole_method/event_interface_spec.rb | 1 + .../library/win32ole/win32ole_method/event_spec.rb | 1 + .../win32ole/win32ole_method/helpcontext_spec.rb | 1 + .../win32ole/win32ole_method/helpfile_spec.rb | 1 + .../win32ole/win32ole_method/helpstring_spec.rb | 1 + .../win32ole/win32ole_method/invkind_spec.rb | 1 + .../win32ole/win32ole_method/invoke_kind_spec.rb | 1 + .../library/win32ole/win32ole_method/name_spec.rb | 1 + .../library/win32ole/win32ole_method/new_spec.rb | 1 + .../win32ole/win32ole_method/offset_vtbl_spec.rb | 1 + .../win32ole/win32ole_method/params_spec.rb | 1 + .../win32ole_method/return_type_detail_spec.rb | 1 + .../win32ole/win32ole_method/return_type_spec.rb | 1 + .../win32ole/win32ole_method/return_vtype_spec.rb | 1 + .../win32ole_method/size_opt_params_spec.rb | 1 + .../win32ole/win32ole_method/size_params_spec.rb | 1 + .../library/win32ole/win32ole_method/to_s_spec.rb | 1 + .../win32ole/win32ole_method/visible_spec.rb | 1 + .../win32ole/win32ole_param/default_spec.rb | 1 + .../library/win32ole/win32ole_param/input_spec.rb | 1 + .../library/win32ole/win32ole_param/name_spec.rb | 1 + .../win32ole_param/ole_type_detail_spec.rb | 1 + .../win32ole/win32ole_param/ole_type_spec.rb | 1 + .../win32ole/win32ole_param/optional_spec.rb | 1 + .../library/win32ole/win32ole_param/retval_spec.rb | 1 + .../library/win32ole/win32ole_param/to_s_spec.rb | 1 + .../library/win32ole/win32ole_type/guid_spec.rb | 1 + .../win32ole/win32ole_type/helpcontext_spec.rb | 1 + .../win32ole/win32ole_type/helpfile_spec.rb | 1 + .../win32ole/win32ole_type/helpstring_spec.rb | 1 + .../win32ole/win32ole_type/major_version_spec.rb | 1 + .../win32ole/win32ole_type/minor_version_spec.rb | 1 + .../library/win32ole/win32ole_type/name_spec.rb | 1 + .../library/win32ole/win32ole_type/new_spec.rb | 1 + .../win32ole/win32ole_type/ole_classes_spec.rb | 1 + .../win32ole/win32ole_type/ole_methods_spec.rb | 1 + .../win32ole/win32ole_type/ole_type_spec.rb | 1 + .../library/win32ole/win32ole_type/progid_spec.rb | 1 + .../library/win32ole/win32ole_type/progids_spec.rb | 1 + .../win32ole/win32ole_type/src_type_spec.rb | 1 + .../library/win32ole/win32ole_type/to_s_spec.rb | 1 + .../win32ole/win32ole_type/typekind_spec.rb | 1 + .../win32ole/win32ole_type/typelibs_spec.rb | 1 + .../win32ole/win32ole_type/variables_spec.rb | 1 + .../library/win32ole/win32ole_type/visible_spec.rb | 1 + .../win32ole/win32ole_variable/name_spec.rb | 1 + .../win32ole_variable/ole_type_detail_spec.rb | 1 + .../win32ole/win32ole_variable/ole_type_spec.rb | 1 + .../win32ole/win32ole_variable/to_s_spec.rb | 1 + .../win32ole/win32ole_variable/value_spec.rb | 1 + .../win32ole_variable/variable_kind_spec.rb | 1 + .../win32ole/win32ole_variable/varkind_spec.rb | 1 + .../win32ole/win32ole_variable/visible_spec.rb | 1 + .../ruby/library/zlib/gzipreader/each_line_spec.rb | 1 + spec/ruby/library/zlib/gzipreader/each_spec.rb | 1 + spec/ruby/library/zlib/inflate/finish_spec.rb | 1 + spec/ruby/shared/kernel/at_exit.rb | 67 ++++++ spec/ruby/shared/kernel/fixtures/END.rb | 3 + spec/ruby/shared/kernel/fixtures/at_exit.rb | 3 + spec/ruby/shared/process/exit.rb | 6 + spec/ruby/shared/rational/Rational.rb | 5 + spec/ruby/shared/rational/truncate.rb | 26 +++ 230 files changed, 1887 insertions(+), 187 deletions(-) create mode 100644 spec/ruby/core/array/all_spec.rb create mode 100644 spec/ruby/core/array/none_spec.rb create mode 100644 spec/ruby/core/array/one_spec.rb create mode 100644 spec/ruby/core/array/shared/iterable_and_tolerating_size_increasing.rb create mode 100644 spec/ruby/core/data/define_spec.rb create mode 100644 spec/ruby/core/data/fixtures/classes.rb create mode 100644 spec/ruby/core/data/initialize_spec.rb create mode 100644 spec/ruby/core/exception/fixtures/thread_fiber_ensure.rb create mode 100644 spec/ruby/core/exception/fixtures/thread_fiber_ensure_non_root_fiber.rb delete mode 100644 spec/ruby/core/kernel/fixtures/at_exit.rb create mode 100644 spec/ruby/shared/kernel/at_exit.rb create mode 100644 spec/ruby/shared/kernel/fixtures/END.rb create mode 100644 spec/ruby/shared/kernel/fixtures/at_exit.rb (limited to 'spec/ruby') diff --git a/spec/ruby/core/array/all_spec.rb b/spec/ruby/core/array/all_spec.rb new file mode 100644 index 0000000000..680e8c26fa --- /dev/null +++ b/spec/ruby/core/array/all_spec.rb @@ -0,0 +1,13 @@ +require_relative '../../spec_helper' +require_relative 'shared/iterable_and_tolerating_size_increasing' + +describe "Array#all?" do + @value_to_return = -> _ { true } + it_behaves_like :array_iterable_and_tolerating_size_increasing, :all? + + it "ignores the block if there is an argument" do + -> { + ['bar', 'foobar'].all?(/bar/) { false }.should == true + }.should complain(/given block not used/) + end +end diff --git a/spec/ruby/core/array/any_spec.rb b/spec/ruby/core/array/any_spec.rb index 09d949fe6e..b51ce62f0f 100644 --- a/spec/ruby/core/array/any_spec.rb +++ b/spec/ruby/core/array/any_spec.rb @@ -1,4 +1,5 @@ require_relative '../../spec_helper' +require_relative 'shared/iterable_and_tolerating_size_increasing' describe "Array#any?" do describe 'with no block given (a default block of { |x| x } is implicit)' do @@ -19,6 +20,9 @@ describe "Array#any?" do end describe 'with a block given' do + @value_to_return = -> _ { false } + it_behaves_like :array_iterable_and_tolerating_size_increasing, :any? + it 'is false if the array is empty' do empty_array = [] empty_array.any? {|v| 1 == 1 }.should == false @@ -34,4 +38,12 @@ describe "Array#any?" do array_with_members.any? {|v| v == 42 }.should == false end end + + describe 'when given a pattern argument' do + it "ignores the block if there is an argument" do + -> { + ['bar', 'foobar'].any?(/bar/) { false }.should == true + }.should complain(/given block not used/) + end + end end diff --git a/spec/ruby/core/array/count_spec.rb b/spec/ruby/core/array/count_spec.rb index eaf275aeb7..e778233c16 100644 --- a/spec/ruby/core/array/count_spec.rb +++ b/spec/ruby/core/array/count_spec.rb @@ -1,4 +1,5 @@ require_relative '../../spec_helper' +require_relative 'shared/iterable_and_tolerating_size_increasing' describe "Array#count" do it "returns the number of elements" do @@ -12,4 +13,14 @@ describe "Array#count" do it "returns the number of element for which the block evaluates to true" do [:a, :b, :c].count { |s| s != :b }.should == 2 end + + it "ignores the block if there is an argument" do + -> { + [:a, :b, :b, :c].count(:b) { |e| e.size > 10 }.should == 2 + }.should complain(/given block not used/) + end + + context "when a block argument given" do + it_behaves_like :array_iterable_and_tolerating_size_increasing, :count + end end diff --git a/spec/ruby/core/array/delete_if_spec.rb b/spec/ruby/core/array/delete_if_spec.rb index 1459cc8d04..10972eee0e 100644 --- a/spec/ruby/core/array/delete_if_spec.rb +++ b/spec/ruby/core/array/delete_if_spec.rb @@ -2,6 +2,7 @@ require_relative '../../spec_helper' require_relative 'fixtures/classes' require_relative 'shared/enumeratorize' require_relative 'shared/delete_if' +require_relative 'shared/iterable_and_tolerating_size_increasing' require_relative '../enumerable/shared/enumeratorized' describe "Array#delete_if" do @@ -47,6 +48,35 @@ describe "Array#delete_if" do -> { ArraySpecs.empty_frozen_array.delete_if {} }.should raise_error(FrozenError) end + it "does not truncate the array is the block raises an exception" do + a = [1, 2, 3] + begin + a.delete_if { raise StandardError, 'Oops' } + rescue + end + + a.should == [1, 2, 3] + end + + it "only removes elements for which the block returns true, keeping the element which raised an error." do + a = [1, 2, 3, 4] + begin + a.delete_if do |e| + case e + when 2 then true + when 3 then raise StandardError, 'Oops' + else false + end + end + rescue StandardError + end + + a.should == [1, 3, 4] + end + it_behaves_like :enumeratorized_with_origin_size, :delete_if, [1,2,3] it_behaves_like :delete_if, :delete_if + + @value_to_return = -> _ { false } + it_behaves_like :array_iterable_and_tolerating_size_increasing, :delete_if end diff --git a/spec/ruby/core/array/drop_while_spec.rb b/spec/ruby/core/array/drop_while_spec.rb index bb783d22a5..94064528aa 100644 --- a/spec/ruby/core/array/drop_while_spec.rb +++ b/spec/ruby/core/array/drop_while_spec.rb @@ -1,7 +1,11 @@ require_relative '../../spec_helper' require_relative 'fixtures/classes' +require_relative 'shared/iterable_and_tolerating_size_increasing' describe "Array#drop_while" do + @value_to_return = -> _ { true } + it_behaves_like :array_iterable_and_tolerating_size_increasing, :drop_while + it "removes elements from the start of the array while the block evaluates to true" do [1, 2, 3, 4].drop_while { |n| n < 4 }.should == [4] end diff --git a/spec/ruby/core/array/each_index_spec.rb b/spec/ruby/core/array/each_index_spec.rb index 75ab61b6f9..3a4bca9251 100644 --- a/spec/ruby/core/array/each_index_spec.rb +++ b/spec/ruby/core/array/each_index_spec.rb @@ -40,3 +40,19 @@ describe "Array#each_index" do it_behaves_like :enumeratorize, :each_index it_behaves_like :enumeratorized_with_origin_size, :each_index, [1,2,3] end + +describe "Array#each_index" do + it "tolerates increasing an array size during iteration" do + array = [:a, :b, :c] + ScratchPad.record [] + i = 0 + + array.each_index do |index| + ScratchPad << index + array << i if i < 100 + i += 1 + end + + ScratchPad.recorded.should == (0..102).to_a # element indices + end +end diff --git a/spec/ruby/core/array/each_spec.rb b/spec/ruby/core/array/each_spec.rb index cf8e9da6d8..57d6082f01 100644 --- a/spec/ruby/core/array/each_spec.rb +++ b/spec/ruby/core/array/each_spec.rb @@ -1,6 +1,7 @@ require_relative '../../spec_helper' require_relative 'fixtures/classes' require_relative 'shared/enumeratorize' +require_relative 'shared/iterable_and_tolerating_size_increasing' require_relative '../enumerable/shared/enumeratorized' # Mutating the array while it is being iterated is discouraged as it can result in confusing behavior. @@ -75,3 +76,7 @@ describe "Array#each" do it_behaves_like :enumeratorize, :each it_behaves_like :enumeratorized_with_origin_size, :each, [1,2,3] end + +describe "Array#each" do + it_behaves_like :array_iterable_and_tolerating_size_increasing, :each +end diff --git a/spec/ruby/core/array/fill_spec.rb b/spec/ruby/core/array/fill_spec.rb index 524728233b..a591444bab 100644 --- a/spec/ruby/core/array/fill_spec.rb +++ b/spec/ruby/core/array/fill_spec.rb @@ -72,6 +72,48 @@ describe "Array#fill" do -> { [].fill(1, 2) {|i|} }.should_not raise_error(ArgumentError) -> { [].fill(1, 2, true) {|i|} }.should raise_error(ArgumentError) end + + it "does not truncate the array is the block raises an exception" do + a = [1, 2, 3] + begin + a.fill { raise StandardError, 'Oops' } + rescue + end + + a.should == [1, 2, 3] + end + + it "only changes elements before error is raised, keeping the element which raised an error." do + a = [1, 2, 3, 4] + begin + a.fill do |i| + case i + when 0 then -1 + when 1 then -2 + when 2 then raise StandardError, 'Oops' + else 0 + end + end + rescue StandardError + end + + a.should == [-1, -2, 3, 4] + end + + it "tolerates increasing an array size during iteration" do + array = [:a, :b, :c] + ScratchPad.record [] + i = 0 + + array.fill do |index| + ScratchPad << index + array << i if i < 100 + i++ + index + end + + ScratchPad.recorded.should == [0, 1, 2] + end end describe "Array#fill with (filler, index, length)" do diff --git a/spec/ruby/core/array/initialize_spec.rb b/spec/ruby/core/array/initialize_spec.rb index a8deed2b84..b9fa77b16e 100644 --- a/spec/ruby/core/array/initialize_spec.rb +++ b/spec/ruby/core/array/initialize_spec.rb @@ -53,7 +53,9 @@ describe "Array#initialize with no arguments" do end it "does not use the given block" do - ->{ [1, 2, 3].send(:initialize) { raise } }.should_not raise_error + -> { + -> { [1, 2, 3].send(:initialize) { raise } }.should_not raise_error + }.should complain(/#{__FILE__}:#{__LINE__-1}: warning: given block not used/, verbose: true) end end diff --git a/spec/ruby/core/array/intersect_spec.rb b/spec/ruby/core/array/intersect_spec.rb index b8c5b1e69a..62ac157278 100644 --- a/spec/ruby/core/array/intersect_spec.rb +++ b/spec/ruby/core/array/intersect_spec.rb @@ -1,17 +1,66 @@ require_relative '../../spec_helper' +require_relative 'fixtures/classes' describe 'Array#intersect?' do ruby_version_is '3.1' do # https://bugs.ruby-lang.org/issues/15198 describe 'when at least one element in two Arrays is the same' do it 'returns true' do - [1, 2].intersect?([2, 3]).should == true + [1, 2].intersect?([2, 3, 4]).should == true + [2, 3, 4].intersect?([1, 2]).should == true end end describe 'when there are no elements in common between two Arrays' do it 'returns false' do - [1, 2].intersect?([3, 4]).should == false + [0, 1, 2].intersect?([3, 4]).should == false + [3, 4].intersect?([0, 1, 2]).should == false + [3, 4].intersect?([]).should == false + [].intersect?([0, 1, 2]).should == false end end + + it "tries to convert the passed argument to an Array using #to_ary" do + obj = mock('[1,2,3]') + obj.should_receive(:to_ary).and_return([1, 2, 3]) + + [1, 2].intersect?(obj).should == true + end + + it "determines equivalence between elements in the sense of eql?" do + obj1 = mock('1') + obj2 = mock('2') + obj1.stub!(:hash).and_return(0) + obj2.stub!(:hash).and_return(0) + obj1.stub!(:eql?).and_return(true) + obj2.stub!(:eql?).and_return(true) + + [obj1].intersect?([obj2]).should == true + + obj1 = mock('3') + obj2 = mock('4') + obj1.stub!(:hash).and_return(0) + obj2.stub!(:hash).and_return(0) + obj1.stub!(:eql?).and_return(false) + obj2.stub!(:eql?).and_return(false) + + [obj1].intersect?([obj2]).should == false + end + + it "does not call to_ary on array subclasses" do + [5, 6].intersect?(ArraySpecs::ToAryArray[1, 2, 5, 6]).should == true + end + + it "properly handles an identical item even when its #eql? isn't reflexive" do + x = mock('x') + x.stub!(:hash).and_return(42) + x.stub!(:eql?).and_return(false) # Stubbed for clarity and latitude in implementation; not actually sent by MRI. + + [x].intersect?([x]).should == true + end + + it "has semantic of !(a & b).empty?" do + [].intersect?([]).should == false + [nil].intersect?([nil]).should == true + end end end diff --git a/spec/ruby/core/array/new_spec.rb b/spec/ruby/core/array/new_spec.rb index 96ec6b8198..b50a4857b0 100644 --- a/spec/ruby/core/array/new_spec.rb +++ b/spec/ruby/core/array/new_spec.rb @@ -26,7 +26,9 @@ describe "Array.new with no arguments" do end it "does not use the given block" do - ->{ Array.new { raise } }.should_not raise_error + -> { + -> { Array.new { raise } }.should_not raise_error + }.should complain(/warning: given block not used/, verbose: true) end end diff --git a/spec/ruby/core/array/none_spec.rb b/spec/ruby/core/array/none_spec.rb new file mode 100644 index 0000000000..31cd8c46d6 --- /dev/null +++ b/spec/ruby/core/array/none_spec.rb @@ -0,0 +1,13 @@ +require_relative '../../spec_helper' +require_relative 'shared/iterable_and_tolerating_size_increasing' + +describe "Array#none?" do + @value_to_return = -> _ { false } + it_behaves_like :array_iterable_and_tolerating_size_increasing, :none? + + it "ignores the block if there is an argument" do + -> { + ['bar', 'foobar'].none?(/baz/) { true }.should == true + }.should complain(/given block not used/) + end +end diff --git a/spec/ruby/core/array/one_spec.rb b/spec/ruby/core/array/one_spec.rb new file mode 100644 index 0000000000..0c61907881 --- /dev/null +++ b/spec/ruby/core/array/one_spec.rb @@ -0,0 +1,13 @@ +require_relative '../../spec_helper' +require_relative 'shared/iterable_and_tolerating_size_increasing' + +describe "Array#one?" do + @value_to_return = -> _ { false } + it_behaves_like :array_iterable_and_tolerating_size_increasing, :one? + + it "ignores the block if there is an argument" do + -> { + ['bar', 'foobar'].one?(/foo/) { false }.should == true + }.should complain(/given block not used/) + end +end diff --git a/spec/ruby/core/array/reject_spec.rb b/spec/ruby/core/array/reject_spec.rb index fcf43fabde..81a467e364 100644 --- a/spec/ruby/core/array/reject_spec.rb +++ b/spec/ruby/core/array/reject_spec.rb @@ -2,6 +2,7 @@ require_relative '../../spec_helper' require_relative 'fixtures/classes' require_relative 'shared/enumeratorize' require_relative 'shared/delete_if' +require_relative 'shared/iterable_and_tolerating_size_increasing' require_relative '../enumerable/shared/enumeratorized' describe "Array#reject" do @@ -47,6 +48,10 @@ describe "Array#reject" do it_behaves_like :enumeratorized_with_origin_size, :reject, [1,2,3] end +describe "Array#reject" do + it_behaves_like :array_iterable_and_tolerating_size_increasing, :reject +end + describe "Array#reject!" do it "removes elements for which block is true" do a = [3, 4, 5, 6, 7, 8, 9, 10, 11] @@ -111,6 +116,11 @@ describe "Array#reject!" do -> { ArraySpecs.empty_frozen_array.reject! {} }.should raise_error(FrozenError) end + it "raises a FrozenError on a frozen array only during iteration if called without a block" do + enum = ArraySpecs.frozen_array.reject! + -> { enum.each {} }.should raise_error(FrozenError) + end + it "does not truncate the array is the block raises an exception" do a = [1, 2, 3] begin @@ -141,3 +151,8 @@ describe "Array#reject!" do it_behaves_like :enumeratorized_with_origin_size, :reject!, [1,2,3] it_behaves_like :delete_if, :reject! end + +describe "Array#reject!" do + @value_to_return = -> _ { false } + it_behaves_like :array_iterable_and_tolerating_size_increasing, :reject! +end diff --git a/spec/ruby/core/array/reverse_each_spec.rb b/spec/ruby/core/array/reverse_each_spec.rb index 97c84a2c2e..59dabcd33d 100644 --- a/spec/ruby/core/array/reverse_each_spec.rb +++ b/spec/ruby/core/array/reverse_each_spec.rb @@ -38,6 +38,20 @@ describe "Array#reverse_each" do [1, 2, 3].reverse_each.size.should == 3 end + it "tolerates increasing an array size during iteration" do + array = [:a, :b, :c] + ScratchPad.record [] + i = 0 + + array.reverse_each do |e| + ScratchPad << e + array.prepend i if i < 100 + i += 1 + end + + ScratchPad.recorded.should == [:c, :a, 1] + end + it_behaves_like :enumeratorize, :reverse_each it_behaves_like :enumeratorized_with_origin_size, :reverse_each, [1,2,3] end diff --git a/spec/ruby/core/array/rindex_spec.rb b/spec/ruby/core/array/rindex_spec.rb index a75099e390..13de88818c 100644 --- a/spec/ruby/core/array/rindex_spec.rb +++ b/spec/ruby/core/array/rindex_spec.rb @@ -68,6 +68,21 @@ describe "Array#rindex" do seen.should == [3] end + it "tolerates increasing an array size during iteration" do + array = [:a, :b, :c] + ScratchPad.record [] + i = 0 + + array.rindex do |e| + ScratchPad << e + array.prepend i if i < 100 + i += 1 + false + end + + ScratchPad.recorded.should == [:c, :a, 1] + end + describe "given no argument and no block" do it "produces an Enumerator" do enum = [4, 2, 1, 5, 1, 3].rindex diff --git a/spec/ruby/core/array/shared/collect.rb b/spec/ruby/core/array/shared/collect.rb index 8d75f7db9a..030302ced6 100644 --- a/spec/ruby/core/array/shared/collect.rb +++ b/spec/ruby/core/array/shared/collect.rb @@ -1,4 +1,5 @@ require_relative '../../enumerable/shared/enumeratorized' +require_relative '../shared/iterable_and_tolerating_size_increasing' describe :array_collect, shared: true do it "returns a copy of array with each element replaced by the value returned by block" do @@ -46,6 +47,8 @@ describe :array_collect, shared: true do @object = [1, 2, 3, 4] end it_should_behave_like :enumeratorized_with_origin_size + + it_should_behave_like :array_iterable_and_tolerating_size_increasing end describe :array_collect_b, shared: true do @@ -102,8 +105,37 @@ describe :array_collect_b, shared: true do end end + it "does not truncate the array is the block raises an exception" do + a = [1, 2, 3] + begin + a.send(@method) { raise StandardError, 'Oops' } + rescue + end + + a.should == [1, 2, 3] + end + + it "only changes elements before error is raised, keeping the element which raised an error." do + a = [1, 2, 3, 4] + begin + a.send(@method) do |e| + case e + when 1 then -1 + when 2 then -2 + when 3 then raise StandardError, 'Oops' + else 0 + end + end + rescue StandardError + end + + a.should == [-1, -2, 3, 4] + end + before :all do @object = [1, 2, 3, 4] end it_should_behave_like :enumeratorized_with_origin_size + + it_should_behave_like :array_iterable_and_tolerating_size_increasing end diff --git a/spec/ruby/core/array/shared/index.rb b/spec/ruby/core/array/shared/index.rb index a9896554f2..a4a0adbab6 100644 --- a/spec/ruby/core/array/shared/index.rb +++ b/spec/ruby/core/array/shared/index.rb @@ -1,3 +1,5 @@ +require_relative '../shared/iterable_and_tolerating_size_increasing' + describe :array_index, shared: true do it "returns the index of the first element == to object" do x = mock('3') @@ -34,4 +36,6 @@ describe :array_index, shared: true do [].send(@method).should be_an_instance_of(Enumerator) end end + + it_should_behave_like :array_iterable_and_tolerating_size_increasing end diff --git a/spec/ruby/core/array/shared/intersection.rb b/spec/ruby/core/array/shared/intersection.rb index 49849b08c2..0b4166ab63 100644 --- a/spec/ruby/core/array/shared/intersection.rb +++ b/spec/ruby/core/array/shared/intersection.rb @@ -11,7 +11,8 @@ describe :array_intersection, shared: true do end it "creates an array with elements in order they are first encountered" do - [ 1, 2, 3, 2, 5 ].send(@method, [ 5, 2, 3, 4 ]).should == [2, 3, 5] + [ 1, 2, 3, 2, 5, 6, 7, 8 ].send(@method, [ 5, 2, 3, 4 ]).should == [2, 3, 5] # array > other + [ 5, 2, 3, 4 ].send(@method, [ 1, 2, 3, 2, 5, 6, 7, 8 ]).should == [5, 2, 3] # array < other end it "does not modify the original Array" do diff --git a/spec/ruby/core/array/shared/iterable_and_tolerating_size_increasing.rb b/spec/ruby/core/array/shared/iterable_and_tolerating_size_increasing.rb new file mode 100644 index 0000000000..3e73bad44b --- /dev/null +++ b/spec/ruby/core/array/shared/iterable_and_tolerating_size_increasing.rb @@ -0,0 +1,25 @@ +describe :array_iterable_and_tolerating_size_increasing, shared: true do + before do + @value_to_return ||= -> _ { nil } + end + + it "tolerates increasing an array size during iteration" do + # The goal is to trigger potential reallocation of internal array storage, so we: + # - use elements of different types, starting with the less generic (Integer) + # - add reasonably big number of new elements (~ 100) + array = [1, 2, 3] # to test some methods we need several uniq elements + array_to_join = [:a, :b, :c] + (4..100).to_a + + ScratchPad.record [] + i = 0 + + array.send(@method) do |e| + ScratchPad << e + array << array_to_join[i] if i < array_to_join.size + i += 1 + @value_to_return.call(e) + end + + ScratchPad.recorded.should == [1, 2, 3] + array_to_join + end +end diff --git a/spec/ruby/core/array/shared/keep_if.rb b/spec/ruby/core/array/shared/keep_if.rb index f26aff028c..43a047c0a7 100644 --- a/spec/ruby/core/array/shared/keep_if.rb +++ b/spec/ruby/core/array/shared/keep_if.rb @@ -1,4 +1,5 @@ require_relative '../../enumerable/shared/enumeratorized' +require_relative '../shared/iterable_and_tolerating_size_increasing' describe :keep_if, shared: true do it "deletes elements for which the block returns a false value" do @@ -56,5 +57,39 @@ describe :keep_if, shared: true do -> { @frozen.send(@method) { false } }.should raise_error(FrozenError) end end + + it "raises a FrozenError on a frozen array only during iteration if called without a block" do + enum = @frozen.send(@method) + -> { enum.each {} }.should raise_error(FrozenError) + end + end + + it "does not truncate the array is the block raises an exception" do + a = [1, 2, 3] + begin + a.send(@method) { raise StandardError, 'Oops' } + rescue + end + + a.should == [1, 2, 3] end + + it "only changes elements before error is raised, keeping the element which raised an error." do + a = [1, 2, 3, 4] + begin + a.send(@method) do |e| + case e + when 2 then false + when 3 then raise StandardError, 'Oops' + else true + end + end + rescue StandardError + end + + a.should == [1, 3, 4] + end + + @value_to_return = -> _ { true } + it_should_behave_like :array_iterable_and_tolerating_size_increasing end diff --git a/spec/ruby/core/array/shared/select.rb b/spec/ruby/core/array/shared/select.rb index 09101e8ab5..9c2cbf76c4 100644 --- a/spec/ruby/core/array/shared/select.rb +++ b/spec/ruby/core/array/shared/select.rb @@ -2,11 +2,14 @@ require_relative '../../../spec_helper' require_relative '../fixtures/classes' require_relative '../shared/enumeratorize' require_relative '../shared/keep_if' +require_relative '../shared/iterable_and_tolerating_size_increasing' require_relative '../../enumerable/shared/enumeratorized' describe :array_select, shared: true do it_should_behave_like :enumeratorize + it_should_behave_like :array_iterable_and_tolerating_size_increasing + before :each do @object = [1,2,3] end diff --git a/spec/ruby/core/array/sort_by_spec.rb b/spec/ruby/core/array/sort_by_spec.rb index 7cea6ec6d3..0334f953f6 100644 --- a/spec/ruby/core/array/sort_by_spec.rb +++ b/spec/ruby/core/array/sort_by_spec.rb @@ -1,5 +1,6 @@ require_relative '../../spec_helper' require_relative 'fixtures/classes' +require_relative 'shared/iterable_and_tolerating_size_increasing' require_relative '../enumerable/shared/enumeratorized' describe "Array#sort_by!" do @@ -31,6 +32,11 @@ describe "Array#sort_by!" do -> { ArraySpecs.empty_frozen_array.sort_by! {}}.should raise_error(FrozenError) end + it "raises a FrozenError on a frozen array only during iteration if called without a block" do + enum = ArraySpecs.frozen_array.sort_by! + -> { enum.each {} }.should raise_error(FrozenError) + end + it "returns the specified value when it would break in the given block" do [1, 2, 3].sort_by!{ break :a }.should == :a end @@ -48,5 +54,32 @@ describe "Array#sort_by!" do [1].sort_by!(&:to_s).should == [1] end + it "does not truncate the array is the block raises an exception" do + a = [1, 2, 3] + begin + a.sort_by! { raise StandardError, 'Oops' } + rescue + end + + a.should == [1, 2, 3] + end + + it "doesn't change array if error is raised" do + a = [4, 3, 2, 1] + begin + a.sort_by! do |e| + raise StandardError, 'Oops' if e == 1 + e + end + rescue StandardError + end + + a.should == [4, 3, 2, 1] + end + it_behaves_like :enumeratorized_with_origin_size, :sort_by!, [1,2,3] end + +describe "Array#sort_by!" do + it_behaves_like :array_iterable_and_tolerating_size_increasing, :sort_by! +end diff --git a/spec/ruby/core/array/sum_spec.rb b/spec/ruby/core/array/sum_spec.rb index 34635d9bc0..1f1d6b2f14 100644 --- a/spec/ruby/core/array/sum_spec.rb +++ b/spec/ruby/core/array/sum_spec.rb @@ -1,4 +1,5 @@ require_relative '../../spec_helper' +require_relative 'shared/iterable_and_tolerating_size_increasing' describe "Array#sum" do it "returns the sum of elements" do @@ -69,3 +70,8 @@ describe "Array#sum" do [b].sum(a).should == 42 end end + +describe "Array#sum" do + @value_to_return = -> _ { 1 } + it_behaves_like :array_iterable_and_tolerating_size_increasing, :sum +end diff --git a/spec/ruby/core/array/take_while_spec.rb b/spec/ruby/core/array/take_while_spec.rb index 363419b265..73f25493c8 100644 --- a/spec/ruby/core/array/take_while_spec.rb +++ b/spec/ruby/core/array/take_while_spec.rb @@ -1,5 +1,6 @@ require_relative '../../spec_helper' require_relative 'fixtures/classes' +require_relative 'shared/iterable_and_tolerating_size_increasing' describe "Array#take_while" do it "returns all elements until the block returns false" do @@ -26,3 +27,8 @@ describe "Array#take_while" do end end end + +describe "Array#take_while" do + @value_to_return = -> _ { true } + it_behaves_like :array_iterable_and_tolerating_size_increasing, :take_while +end diff --git a/spec/ruby/core/array/to_h_spec.rb b/spec/ruby/core/array/to_h_spec.rb index f5a7e546e6..f4578211a1 100644 --- a/spec/ruby/core/array/to_h_spec.rb +++ b/spec/ruby/core/array/to_h_spec.rb @@ -1,5 +1,6 @@ require_relative '../../spec_helper' require_relative 'fixtures/classes' +require_relative 'shared/iterable_and_tolerating_size_increasing' describe "Array#to_h" do it "converts empty array to empty hash" do @@ -77,3 +78,8 @@ describe "Array#to_h" do end end end + +describe "Array#to_h" do + @value_to_return = -> e { [e, e.to_s] } + it_behaves_like :array_iterable_and_tolerating_size_increasing, :to_h +end diff --git a/spec/ruby/core/array/uniq_spec.rb b/spec/ruby/core/array/uniq_spec.rb index 4461cae16b..905ab59634 100644 --- a/spec/ruby/core/array/uniq_spec.rb +++ b/spec/ruby/core/array/uniq_spec.rb @@ -1,5 +1,6 @@ require_relative '../../spec_helper' require_relative 'fixtures/classes' +require_relative 'shared/iterable_and_tolerating_size_increasing' describe "Array#uniq" do it "returns an array with no duplicates" do @@ -131,6 +132,11 @@ describe "Array#uniq" do end end +describe "Array#uniq" do + @value_to_return = -> e { e } + it_behaves_like :array_iterable_and_tolerating_size_increasing, :uniq +end + describe "Array#uniq!" do it "modifies the array in place" do a = [ "a", "a", "b", "b", "c" ] @@ -214,4 +220,32 @@ describe "Array#uniq!" do a.uniq! a.should == [x] end + + it "does not truncate the array is the block raises an exception" do + a = [1, 2, 3] + begin + a.send(@method) { raise StandardError, 'Oops' } + rescue + end + + a.should == [1, 2, 3] + end + + it "doesn't change array if error is raised" do + a = [1, 1, 2, 2, 3, 3, 4, 4] + begin + a.send(@method) do |e| + raise StandardError, 'Oops' if e == 3 + e + end + rescue StandardError + end + + a.should == [1, 1, 2, 2, 3, 3, 4, 4] + end +end + +describe "Array#uniq!" do + @value_to_return = -> e { e } + it_behaves_like :array_iterable_and_tolerating_size_increasing, :uniq! end diff --git a/spec/ruby/core/basicobject/fixtures/classes.rb b/spec/ruby/core/basicobject/fixtures/classes.rb index d1785afe31..ed5a2dda17 100644 --- a/spec/ruby/core/basicobject/fixtures/classes.rb +++ b/spec/ruby/core/basicobject/fixtures/classes.rb @@ -15,8 +15,231 @@ module BasicObjectSpecs include InstExec end - module InstEvalCVar - instance_eval { @@count = 2 } + module InstEval + module CVar + module Get + class ReceiverScope + @@cvar = :value_defined_in_receiver_scope + end + + class BlockDefinitionScope + @@cvar = :value_defined_in_block_definition_scope + + def block + -> * { @@cvar } + end + end + + class CallerScope + @@cvar = :value_defined_in_caller_scope + + def get_class_variable_with_string(obj) + obj.instance_eval("@@cvar") + end + + def get_class_variable_with_block(obj, block) + obj.instance_eval(&block) + end + end + + class CallerWithoutCVarScope + def get_class_variable_with_string(obj) + obj.instance_eval("@@cvar") + end + end + + ReceiverWithCVarDefinedInSingletonClass = Class.new.new.tap do |obj| + obj.singleton_class.class_variable_set(:@@cvar, :value_defined_in_receiver_singleton_class) + end + end + + module Set + class ReceiverScope + end + + class BlockDefinitionScope + def self.get_class_variable + @@cvar + end + + def block_to_assign(value) + -> * { @@cvar = value } + end + end + + class CallerScope + def self.get_class_variable + @@cvar + end + + def set_class_variable_with_string(obj, value) + obj.instance_eval("@@cvar=#{value.inspect}") + end + + def set_class_variable_with_block(obj, block) + obj.instance_eval(&block) + end + end + end + end + end + + module InstEval + module Constants + module ConstantInReceiverSingletonClass + module ReceiverScope + FOO = :ReceiverScope + + class ReceiverParent + FOO = :ReceiverParent + end + + class Receiver < ReceiverParent + FOO = :Receiver + + def initialize + self.singleton_class.const_set(:FOO, :singleton_class) + end + end + end + + module CallerScope + FOO = :CallerScope + + class CallerParent + FOO = :CallerParent + end + + class Caller < CallerParent + FOO = :Caller + + def get_constant_with_string(receiver) + receiver.instance_eval("FOO") + end + end + end + end + + module ConstantInReceiverClass + module ReceiverScope + FOO = :ReceiverScope + + class ReceiverParent + FOO = :ReceiverParent + end + + class Receiver < ReceiverParent + FOO = :Receiver + end + end + + module CallerScope + FOO = :CallerScope + + class CallerParent + FOO = :CallerParent + end + + class Caller < CallerParent + FOO = :Caller + + def get_constant_with_string(receiver) + receiver.instance_eval("FOO") + end + end + end + end + + module ConstantInCallerClass + module ReceiverScope + FOO = :ReceiverScope + + class ReceiverParent + FOO = :ReceiverParent + end + + class Receiver < ReceiverParent + # FOO is not declared in a receiver class + end + end + + module CallerScope + FOO = :CallerScope + + class CallerParent + FOO = :CallerParent + end + + class Caller < CallerParent + FOO = :Caller + + def get_constant_with_string(receiver) + receiver.instance_eval("FOO") + end + end + end + end + + module ConstantInCallerOuterScopes + module ReceiverScope + FOO = :ReceiverScope + + class ReceiverParent + FOO = :ReceiverParent + end + + class Receiver < ReceiverParent + # FOO is not declared in a receiver class + end + end + + module CallerScope + FOO = :CallerScope + + class CallerParent + FOO = :CallerParent + end + + class Caller < CallerParent + # FOO is not declared in a caller class + + def get_constant_with_string(receiver) + receiver.instance_eval("FOO") + end + end + end + end + + module ConstantInReceiverParentClass + module ReceiverScope + FOO = :ReceiverScope + + class ReceiverParent + FOO = :ReceiverParent + end + + class Receiver < ReceiverParent + # FOO is not declared in a receiver class + end + end + + module CallerScope + # FOO is not declared in a caller outer scopes + + class CallerParent + FOO = :CallerParent + end + + class Caller < CallerParent + # FOO is not declared in a caller class + + def get_constant_with_string(receiver) + receiver.instance_eval("FOO") + end + end + end + end + end end class InstEvalConst @@ -26,7 +249,6 @@ module BasicObjectSpecs module InstEvalOuter module Inner obj = InstEvalConst.new - X_BY_STR = obj.instance_eval("INST_EVAL_CONST_X") rescue nil X_BY_BLOCK = obj.instance_eval { INST_EVAL_CONST_X } rescue nil end end diff --git a/spec/ruby/core/basicobject/instance_eval_spec.rb b/spec/ruby/core/basicobject/instance_eval_spec.rb index 350b08a30e..699c965171 100644 --- a/spec/ruby/core/basicobject/instance_eval_spec.rb +++ b/spec/ruby/core/basicobject/instance_eval_spec.rb @@ -89,6 +89,18 @@ describe "BasicObject#instance_eval" do BasicObjectSpecs::IVars.new.instance_eval("@secret").should == 99 end + it "raises TypeError for frozen objects when tries to set receiver's instance variables" do + -> { nil.instance_eval { @foo = 42 } }.should raise_error(FrozenError, "can't modify frozen NilClass: nil") + -> { true.instance_eval { @foo = 42 } }.should raise_error(FrozenError, "can't modify frozen TrueClass: true") + -> { false.instance_eval { @foo = 42 } }.should raise_error(FrozenError, "can't modify frozen FalseClass: false") + -> { 1.instance_eval { @foo = 42 } }.should raise_error(FrozenError, "can't modify frozen Integer: 1") + -> { :symbol.instance_eval { @foo = 42 } }.should raise_error(FrozenError, "can't modify frozen Symbol: :symbol") + + obj = Object.new + obj.freeze + -> { obj.instance_eval { @foo = 42 } }.should raise_error(FrozenError) + end + it "treats block-local variables as local to the block" do prc = instance_eval <<-CODE proc do |x, prc| @@ -105,11 +117,6 @@ describe "BasicObject#instance_eval" do prc.call(false, prc).should == 1 end - it "sets class variables in the receiver" do - BasicObjectSpecs::InstEvalCVar.class_variables.should include(:@@count) - BasicObjectSpecs::InstEvalCVar.send(:class_variable_get, :@@count).should == 2 - end - it "makes the receiver metaclass the scoped class when used with a string" do obj = Object.new obj.instance_eval %{ @@ -119,8 +126,52 @@ describe "BasicObject#instance_eval" do obj.singleton_class.const_get(:B).should be_an_instance_of(Class) end - it "gets constants in the receiver if a string given" do - BasicObjectSpecs::InstEvalOuter::Inner::X_BY_STR.should == 2 + describe "constants lookup when a String given" do + it "looks in the receiver singleton class first" do + receiver = BasicObjectSpecs::InstEval::Constants::ConstantInReceiverSingletonClass::ReceiverScope::Receiver.new + caller = BasicObjectSpecs::InstEval::Constants::ConstantInReceiverSingletonClass::CallerScope::Caller.new + + caller.get_constant_with_string(receiver).should == :singleton_class + end + + ruby_version_is ""..."3.1" do + it "looks in the caller scope next" do + receiver = BasicObjectSpecs::InstEval::Constants::ConstantInReceiverClass::ReceiverScope::Receiver.new + caller = BasicObjectSpecs::InstEval::Constants::ConstantInReceiverClass::CallerScope::Caller.new + + caller.get_constant_with_string(receiver).should == :Caller + end + end + + ruby_version_is "3.1" do + it "looks in the receiver class next" do + receiver = BasicObjectSpecs::InstEval::Constants::ConstantInReceiverClass::ReceiverScope::Receiver.new + caller = BasicObjectSpecs::InstEval::Constants::ConstantInReceiverClass::CallerScope::Caller.new + + caller.get_constant_with_string(receiver).should == :Receiver + end + end + + it "looks in the caller class next" do + receiver = BasicObjectSpecs::InstEval::Constants::ConstantInCallerClass::ReceiverScope::Receiver.new + caller = BasicObjectSpecs::InstEval::Constants::ConstantInCallerClass::CallerScope::Caller.new + + caller.get_constant_with_string(receiver).should == :Caller + end + + it "looks in the caller outer scopes next" do + receiver = BasicObjectSpecs::InstEval::Constants::ConstantInCallerOuterScopes::ReceiverScope::Receiver.new + caller = BasicObjectSpecs::InstEval::Constants::ConstantInCallerOuterScopes::CallerScope::Caller.new + + caller.get_constant_with_string(receiver).should == :CallerScope + end + + it "looks in the receiver class hierarchy next" do + receiver = BasicObjectSpecs::InstEval::Constants::ConstantInReceiverParentClass::ReceiverScope::Receiver.new + caller = BasicObjectSpecs::InstEval::Constants::ConstantInReceiverParentClass::CallerScope::Caller.new + + caller.get_constant_with_string(receiver).should == :ReceiverParent + end end it "doesn't get constants in the receiver if a block given" do @@ -136,17 +187,51 @@ describe "BasicObject#instance_eval" do end.should raise_error(TypeError) end -quarantine! do # Not clean, leaves cvars lying around to break other specs - it "scopes class var accesses in the caller when called on an Integer" do - # Integer can take instance vars - Integer.class_eval "@@__tmp_instance_eval_spec = 1" - (defined? @@__tmp_instance_eval_spec).should be_nil + describe "class variables lookup" do + it "gets class variables in the caller class when called with a String" do + receiver = BasicObjectSpecs::InstEval::CVar::Get::ReceiverScope.new + caller = BasicObjectSpecs::InstEval::CVar::Get::CallerScope.new + + caller.get_class_variable_with_string(receiver).should == :value_defined_in_caller_scope + end + + it "gets class variables in the block definition scope when called with a block" do + receiver = BasicObjectSpecs::InstEval::CVar::Get::ReceiverScope.new + caller = BasicObjectSpecs::InstEval::CVar::Get::CallerScope.new + block = BasicObjectSpecs::InstEval::CVar::Get::BlockDefinitionScope.new.block + + caller.get_class_variable_with_block(receiver, block).should == :value_defined_in_block_definition_scope + end + + it "sets class variables in the caller class when called with a String" do + receiver = BasicObjectSpecs::InstEval::CVar::Set::ReceiverScope.new + caller = BasicObjectSpecs::InstEval::CVar::Set::CallerScope.new + + caller.set_class_variable_with_string(receiver, 1) + BasicObjectSpecs::InstEval::CVar::Set::CallerScope.get_class_variable.should == 1 + end + + it "sets class variables in the block definition scope when called with a block" do + receiver = BasicObjectSpecs::InstEval::CVar::Set::ReceiverScope.new + caller = BasicObjectSpecs::InstEval::CVar::Set::CallerScope.new + block = BasicObjectSpecs::InstEval::CVar::Set::BlockDefinitionScope.new.block_to_assign(1) + + caller.set_class_variable_with_block(receiver, block) + BasicObjectSpecs::InstEval::CVar::Set::BlockDefinitionScope.get_class_variable.should == 1 + end + + it "does not have access to class variables in the receiver class when called with a String" do + receiver = BasicObjectSpecs::InstEval::CVar::Get::ReceiverScope.new + caller = BasicObjectSpecs::InstEval::CVar::Get::CallerWithoutCVarScope.new + -> { caller.get_class_variable_with_string(receiver) }.should raise_error(NameError, /uninitialized class variable @@cvar/) + end - @@__tmp_instance_eval_spec = 2 - 1.instance_eval { @@__tmp_instance_eval_spec }.should == 2 - Integer.__send__(:remove_class_variable, :@@__tmp_instance_eval_spec) + it "does not have access to class variables in the receiver's singleton class when called with a String" do + receiver = BasicObjectSpecs::InstEval::CVar::Get::ReceiverWithCVarDefinedInSingletonClass + caller = BasicObjectSpecs::InstEval::CVar::Get::CallerWithoutCVarScope.new + -> { caller.get_class_variable_with_string(receiver) }.should raise_error(NameError, /uninitialized class variable @@cvar/) + end end -end it "raises a TypeError when defining methods on numerics" do -> do diff --git a/spec/ruby/core/basicobject/method_missing_spec.rb b/spec/ruby/core/basicobject/method_missing_spec.rb index b048780ee8..a29d4375bc 100644 --- a/spec/ruby/core/basicobject/method_missing_spec.rb +++ b/spec/ruby/core/basicobject/method_missing_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../spec_helper" require_relative '../../shared/basicobject/method_missing' describe "BasicObject#method_missing" do diff --git a/spec/ruby/core/data/define_spec.rb b/spec/ruby/core/data/define_spec.rb new file mode 100644 index 0000000000..abfdd3e6a7 --- /dev/null +++ b/spec/ruby/core/data/define_spec.rb @@ -0,0 +1,26 @@ +require_relative '../../spec_helper' +require_relative 'fixtures/classes' + +ruby_version_is "3.2" do + describe "Data.define" do + it "accepts no arguments" do + empty_data = Data.define + empty_data.members.should == [] + end + + it "accepts symbols" do + movie_with_symbol = Data.define(:title, :year) + movie_with_symbol.members.should == [:title, :year] + end + + it "accepts strings" do + movie_with_string = Data.define("title", "year") + movie_with_string.members.should == [:title, :year] + end + + it "accepts a mix of strings and symbols" do + blockbuster_movie = Data.define("title", :year, "genre") + blockbuster_movie.members.should == [:title, :year, :genre] + end + end +end diff --git a/spec/ruby/core/data/fixtures/classes.rb b/spec/ruby/core/data/fixtures/classes.rb new file mode 100644 index 0000000000..d1e10e02ed --- /dev/null +++ b/spec/ruby/core/data/fixtures/classes.rb @@ -0,0 +1,5 @@ +module DataSpecs + ruby_version_is "3.2" do + Measure = Data.define(:amount, :unit) + end +end diff --git a/spec/ruby/core/data/initialize_spec.rb b/spec/ruby/core/data/initialize_spec.rb new file mode 100644 index 0000000000..94470cd108 --- /dev/null +++ b/spec/ruby/core/data/initialize_spec.rb @@ -0,0 +1,58 @@ +require_relative '../../spec_helper' +require_relative 'fixtures/classes' + +ruby_version_is "3.2" do + describe "Data#initialize" do + it "accepts positional arguments" do + data = DataSpecs::Measure.new(42, "km") + + data.amount.should == 42 + data.unit.should == "km" + end + + it "accepts alternative positional arguments" do + data = DataSpecs::Measure[42, "km"] + + data.amount.should == 42 + data.unit.should == "km" + end + + it "accepts keyword arguments" do + data = DataSpecs::Measure.new(amount: 42, unit: "km") + + data.amount.should == 42 + data.unit.should == "km" + end + + it "accepts alternative keyword arguments" do + data = DataSpecs::Measure[amount: 42, unit: "km"] + + data.amount.should == 42 + data.unit.should == "km" + end + + it "raises ArgumentError if no arguments are given" do + -> { + DataSpecs::Measure.new + }.should raise_error(ArgumentError) { |e| + e.message.should.include?("missing keywords: :amount, :unit") + } + end + + it "raises ArgumentError if at least one argument is missing" do + -> { + DataSpecs::Measure.new(unit: "km") + }.should raise_error(ArgumentError) { |e| + e.message.should.include?("missing keyword: :amount") + } + end + + it "raises ArgumentError if unknown keyword is given" do + -> { + DataSpecs::Measure.new(amount: 42, unit: "km", system: "metric") + }.should raise_error(ArgumentError) { |e| + e.message.should.include?("unknown keyword: :system") + } + end + end +end diff --git a/spec/ruby/core/encoding/invalid_byte_sequence_error/destination_encoding_name_spec.rb b/spec/ruby/core/encoding/invalid_byte_sequence_error/destination_encoding_name_spec.rb index f5fa6f55e3..2b15fc1a0f 100644 --- a/spec/ruby/core/encoding/invalid_byte_sequence_error/destination_encoding_name_spec.rb +++ b/spec/ruby/core/encoding/invalid_byte_sequence_error/destination_encoding_name_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" require_relative '../fixtures/classes' describe "Encoding::InvalidByteSequenceError#destination_encoding_name" do diff --git a/spec/ruby/core/encoding/invalid_byte_sequence_error/destination_encoding_spec.rb b/spec/ruby/core/encoding/invalid_byte_sequence_error/destination_encoding_spec.rb index 43be3ddd71..c2ed6de1d8 100644 --- a/spec/ruby/core/encoding/invalid_byte_sequence_error/destination_encoding_spec.rb +++ b/spec/ruby/core/encoding/invalid_byte_sequence_error/destination_encoding_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" require_relative '../fixtures/classes' describe "Encoding::InvalidByteSequenceError#destination_encoding" do diff --git a/spec/ruby/core/encoding/invalid_byte_sequence_error/error_bytes_spec.rb b/spec/ruby/core/encoding/invalid_byte_sequence_error/error_bytes_spec.rb index a8f7354b16..d2fc360dce 100644 --- a/spec/ruby/core/encoding/invalid_byte_sequence_error/error_bytes_spec.rb +++ b/spec/ruby/core/encoding/invalid_byte_sequence_error/error_bytes_spec.rb @@ -1,4 +1,5 @@ # -*- encoding: binary -*- +require_relative "../../../spec_helper" require_relative '../fixtures/classes' describe "Encoding::InvalidByteSequenceError#error_bytes" do diff --git a/spec/ruby/core/encoding/invalid_byte_sequence_error/readagain_bytes_spec.rb b/spec/ruby/core/encoding/invalid_byte_sequence_error/readagain_bytes_spec.rb index 93823b5db4..9866310c25 100644 --- a/spec/ruby/core/encoding/invalid_byte_sequence_error/readagain_bytes_spec.rb +++ b/spec/ruby/core/encoding/invalid_byte_sequence_error/readagain_bytes_spec.rb @@ -1,4 +1,5 @@ # -*- encoding: binary -*- +require_relative "../../../spec_helper" require_relative '../fixtures/classes' describe "Encoding::InvalidByteSequenceError#readagain_bytes" do diff --git a/spec/ruby/core/encoding/invalid_byte_sequence_error/source_encoding_name_spec.rb b/spec/ruby/core/encoding/invalid_byte_sequence_error/source_encoding_name_spec.rb index bd3a51cbc5..a9464114a8 100644 --- a/spec/ruby/core/encoding/invalid_byte_sequence_error/source_encoding_name_spec.rb +++ b/spec/ruby/core/encoding/invalid_byte_sequence_error/source_encoding_name_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" require_relative '../fixtures/classes' describe "Encoding::UndefinedConversionError#source_encoding_name" do diff --git a/spec/ruby/core/encoding/invalid_byte_sequence_error/source_encoding_spec.rb b/spec/ruby/core/encoding/invalid_byte_sequence_error/source_encoding_spec.rb index f43d6d5830..7fdc0a122b 100644 --- a/spec/ruby/core/encoding/invalid_byte_sequence_error/source_encoding_spec.rb +++ b/spec/ruby/core/encoding/invalid_byte_sequence_error/source_encoding_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" require_relative '../fixtures/classes' describe "Encoding::InvalidByteSequenceError#source_encoding" do diff --git a/spec/ruby/core/encoding/name_spec.rb b/spec/ruby/core/encoding/name_spec.rb index 5eadb1d2f5..dce9347978 100644 --- a/spec/ruby/core/encoding/name_spec.rb +++ b/spec/ruby/core/encoding/name_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../spec_helper" require_relative 'shared/name' describe "Encoding#name" do diff --git a/spec/ruby/core/encoding/to_s_spec.rb b/spec/ruby/core/encoding/to_s_spec.rb index 82d282386b..bab394a888 100644 --- a/spec/ruby/core/encoding/to_s_spec.rb +++ b/spec/ruby/core/encoding/to_s_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../spec_helper" require_relative 'shared/name' describe "Encoding#to_s" do diff --git a/spec/ruby/core/encoding/undefined_conversion_error/destination_encoding_name_spec.rb b/spec/ruby/core/encoding/undefined_conversion_error/destination_encoding_name_spec.rb index 106fc7ecac..a51a9f46a0 100644 --- a/spec/ruby/core/encoding/undefined_conversion_error/destination_encoding_name_spec.rb +++ b/spec/ruby/core/encoding/undefined_conversion_error/destination_encoding_name_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" require_relative '../fixtures/classes' describe "Encoding::UndefinedConversionError#destination_encoding_name" do diff --git a/spec/ruby/core/encoding/undefined_conversion_error/destination_encoding_spec.rb b/spec/ruby/core/encoding/undefined_conversion_error/destination_encoding_spec.rb index c6e24732fd..905556407c 100644 --- a/spec/ruby/core/encoding/undefined_conversion_error/destination_encoding_spec.rb +++ b/spec/ruby/core/encoding/undefined_conversion_error/destination_encoding_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" require_relative '../fixtures/classes' describe "Encoding::UndefinedConversionError#destination_encoding" do diff --git a/spec/ruby/core/encoding/undefined_conversion_error/error_char_spec.rb b/spec/ruby/core/encoding/undefined_conversion_error/error_char_spec.rb index 780d81c1ee..9cb55e6d95 100644 --- a/spec/ruby/core/encoding/undefined_conversion_error/error_char_spec.rb +++ b/spec/ruby/core/encoding/undefined_conversion_error/error_char_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" require_relative '../fixtures/classes' describe "Encoding::UndefinedConversionError#error_char" do diff --git a/spec/ruby/core/encoding/undefined_conversion_error/source_encoding_name_spec.rb b/spec/ruby/core/encoding/undefined_conversion_error/source_encoding_name_spec.rb index 3b697cb82f..d5e60e78db 100644 --- a/spec/ruby/core/encoding/undefined_conversion_error/source_encoding_name_spec.rb +++ b/spec/ruby/core/encoding/undefined_conversion_error/source_encoding_name_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" require_relative '../fixtures/classes' describe "Encoding::UndefinedConversionError#source_encoding_name" do diff --git a/spec/ruby/core/encoding/undefined_conversion_error/source_encoding_spec.rb b/spec/ruby/core/encoding/undefined_conversion_error/source_encoding_spec.rb index 9101d51e11..de456a4b5a 100644 --- a/spec/ruby/core/encoding/undefined_conversion_error/source_encoding_spec.rb +++ b/spec/ruby/core/encoding/undefined_conversion_error/source_encoding_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" require_relative '../fixtures/classes' describe "Encoding::UndefinedConversionError#source_encoding" do diff --git a/spec/ruby/core/enumerable/all_spec.rb b/spec/ruby/core/enumerable/all_spec.rb index 0ded1e8eba..160cd52628 100644 --- a/spec/ruby/core/enumerable/all_spec.rb +++ b/spec/ruby/core/enumerable/all_spec.rb @@ -177,5 +177,11 @@ describe "Enumerable#all?" do multi.all?(pattern).should == true pattern.yielded.should == [[[1, 2]], [[3, 4, 5]], [[6, 7, 8, 9]]] end + + it "ignores the block if there is an argument" do + -> { + EnumerableSpecs::Numerous.new(1, 2, 3, 4, 5).all?(String) { true }.should == false + }.should complain(/given block not used/) + end end end diff --git a/spec/ruby/core/enumerable/any_spec.rb b/spec/ruby/core/enumerable/any_spec.rb index 355cd0c290..243f8735d5 100644 --- a/spec/ruby/core/enumerable/any_spec.rb +++ b/spec/ruby/core/enumerable/any_spec.rb @@ -190,5 +190,11 @@ describe "Enumerable#any?" do multi.any?(pattern).should == false pattern.yielded.should == [[[1, 2]], [[3, 4, 5]], [[6, 7, 8, 9]]] end + + it "ignores the block if there is an argument" do + -> { + EnumerableSpecs::Numerous.new(1, 2, 3, 4, 5).any?(String) { true }.should == false + }.should complain(/given block not used/) + end end end diff --git a/spec/ruby/core/enumerable/chunk_spec.rb b/spec/ruby/core/enumerable/chunk_spec.rb index c5579d67fa..ed6304307f 100644 --- a/spec/ruby/core/enumerable/chunk_spec.rb +++ b/spec/ruby/core/enumerable/chunk_spec.rb @@ -29,6 +29,11 @@ describe "Enumerable#chunk" do result.should == [[1, [1, 2]], [0, [3]], [1, [2]], [0, [3]], [1, [2, 1]]] end + it "returns a partitioned Array of values" do + e = EnumerableSpecs::Numerous.new(1,2,3) + e.chunk { |x| x > 2 }.map(&:last).should == [[1, 2], [3]] + end + it "returns elements for which the block returns :_alone in separate Arrays" do e = EnumerableSpecs::Numerous.new(1, 2, 3, 2, 1) result = e.chunk { |x| x < 2 && :_alone }.to_a diff --git a/spec/ruby/core/enumerable/none_spec.rb b/spec/ruby/core/enumerable/none_spec.rb index 99bb7f7a4e..fb42f13386 100644 --- a/spec/ruby/core/enumerable/none_spec.rb +++ b/spec/ruby/core/enumerable/none_spec.rb @@ -143,5 +143,11 @@ describe "Enumerable#none?" do multi.none?(pattern).should == true pattern.yielded.should == [[[1, 2]], [[3, 4, 5]], [[6, 7, 8, 9]]] end + + it "ignores the block if there is an argument" do + -> { + EnumerableSpecs::Numerous.new(1, 2, 3, 4, 5).none?(String) { true }.should == true + }.should complain(/given block not used/) + end end end diff --git a/spec/ruby/core/enumerable/one_spec.rb b/spec/ruby/core/enumerable/one_spec.rb index 47bfd65a0f..4bf8623d2e 100644 --- a/spec/ruby/core/enumerable/one_spec.rb +++ b/spec/ruby/core/enumerable/one_spec.rb @@ -83,7 +83,6 @@ describe "Enumerable#one?" do end end - describe 'when given a pattern argument' do it "calls `===` on the pattern the return value " do pattern = EnumerableSpecs::Pattern.new { |x| x == 1 } @@ -145,5 +144,11 @@ describe "Enumerable#one?" do multi.one?(pattern).should == false pattern.yielded.should == [[[1, 2]], [[3, 4, 5]], [[6, 7, 8, 9]]] end + + it "ignores the block if there is an argument" do + -> { + EnumerableSpecs::Numerous.new(1, 2, 3, 4, "5").one?(String) { false }.should == true + }.should complain(/given block not used/) + end end end diff --git a/spec/ruby/core/enumerable/shared/inject.rb b/spec/ruby/core/enumerable/shared/inject.rb index c5907f92d8..a934d039c5 100644 --- a/spec/ruby/core/enumerable/shared/inject.rb +++ b/spec/ruby/core/enumerable/shared/inject.rb @@ -1,3 +1,5 @@ +require_relative '../../array/shared/iterable_and_tolerating_size_increasing' + describe :enumerable_inject, shared: true do it "with argument takes a block with an accumulator (with argument as initial value) and the current element. Value of block becomes new accumulator" do a = [] @@ -17,8 +19,13 @@ describe :enumerable_inject, shared: true do end it "ignores the block if two arguments" do - EnumerableSpecs::Numerous.new(1, 2, 3).send(@method, 10, :-) { raise "we never get here"}.should == 4 - [].send(@method, 3, :+) { raise "we never get here"}.should == 3 + -> { + EnumerableSpecs::Numerous.new(1, 2, 3).send(@method, 10, :-) { raise "we never get here"}.should == 4 + }.should complain(/#{__FILE__}:#{__LINE__-1}: warning: given block not used/, verbose: true) + + -> { + [1, 2, 3].send(@method, 10, :-) { raise "we never get here"}.should == 4 + }.should complain(/#{__FILE__}:#{__LINE__-1}: warning: given block not used/, verbose: true) end it "can take a symbol argument" do @@ -31,10 +38,10 @@ describe :enumerable_inject, shared: true do a.should == [[2, 5], [5, 3], [3, 6], [6, 1], [1, 4]] end - it "gathers whole arrays as elements when each yields multiple" do - multi = EnumerableSpecs::YieldsMulti.new - multi.send(@method, []) {|acc, e| acc << e }.should == [[1, 2], [3, 4, 5], [6, 7, 8, 9]] - end + it "gathers whole arrays as elements when each yields multiple" do + multi = EnumerableSpecs::YieldsMulti.new + multi.send(@method, []) {|acc, e| acc << e }.should == [[1, 2], [3, 4, 5], [6, 7, 8, 9]] + end it "with inject arguments(legacy rubycon)" do # with inject argument @@ -68,6 +75,22 @@ describe :enumerable_inject, shared: true do EnumerableSpecs::EachDefiner.new().send(@method) {|acc,x| 999 }.should == nil end + it "tolerates increasing a collection size during iterating Array" do + array = [:a, :b, :c] + ScratchPad.record [] + i = 0 + + array.send(@method, nil) do |_, e| + ScratchPad << e + array << i if i < 100 + i += 1 + end + + actual = ScratchPad.recorded + expected = [:a, :b, :c] + (0..99).to_a + actual.sort_by(&:to_s).should == expected.sort_by(&:to_s) + end + ruby_bug '#18635', ''...'3.2' do it "raises an ArgumentError when no parameters or block is given" do -> { [1,2].send(@method) }.should raise_error(ArgumentError) diff --git a/spec/ruby/core/enumerator/chain/inspect_spec.rb b/spec/ruby/core/enumerator/chain/inspect_spec.rb index a0450c808a..9b5a442b75 100644 --- a/spec/ruby/core/enumerator/chain/inspect_spec.rb +++ b/spec/ruby/core/enumerator/chain/inspect_spec.rb @@ -11,4 +11,8 @@ describe "Enumerator::Chain#inspect" do obj.should_receive(:inspect).and_return('some desc') Enumerator::Chain.new(obj).inspect.should == "#" end + + it "returns a not initialized representation if #initialized is not called yet" do + Enumerator::Chain.allocate.inspect.should == "#" + end end diff --git a/spec/ruby/core/enumerator/inspect_spec.rb b/spec/ruby/core/enumerator/inspect_spec.rb index 3bcf07e754..7e97864246 100644 --- a/spec/ruby/core/enumerator/inspect_spec.rb +++ b/spec/ruby/core/enumerator/inspect_spec.rb @@ -14,4 +14,9 @@ describe "Enumerator#inspect" do (1..3).each.each_slice(2).inspect.should == "#:each_slice(2)>" end end + + it "returns a not initialized representation if #initialized is not called yet" do + Enumerator.allocate.inspect.should == "#" + Enumerator::Lazy.allocate.inspect.should == "#" + end end diff --git a/spec/ruby/core/enumerator/lazy/compact_spec.rb b/spec/ruby/core/enumerator/lazy/compact_spec.rb index 80b6f9481d..e678bc71eb 100644 --- a/spec/ruby/core/enumerator/lazy/compact_spec.rb +++ b/spec/ruby/core/enumerator/lazy/compact_spec.rb @@ -1,4 +1,5 @@ require_relative '../../../spec_helper' +require_relative 'fixtures/classes' ruby_version_is '3.1' do describe "Enumerator::Lazy#compact" do @@ -7,5 +8,9 @@ ruby_version_is '3.1' do arr.should be_an_instance_of(Enumerator::Lazy) arr.force.should == [1, 3, false, 5] end + + it "sets #size to nil" do + Enumerator::Lazy.new(Object.new, 100) {}.compact.size.should == nil + end end end diff --git a/spec/ruby/core/exception/fixtures/thread_fiber_ensure.rb b/spec/ruby/core/exception/fixtures/thread_fiber_ensure.rb new file mode 100644 index 0000000000..c109ec6247 --- /dev/null +++ b/spec/ruby/core/exception/fixtures/thread_fiber_ensure.rb @@ -0,0 +1,22 @@ +ready = false +t = Thread.new do + f = Fiber.new do + begin + Fiber.yield + ensure + STDERR.puts "suspended fiber ensure" + end + end + f.resume + + begin + ready = true + sleep + ensure + STDERR.puts "current fiber ensure" + end +end + +Thread.pass until ready && t.stop? + +# let the program end, it's the same as #exit or an exception for this behavior diff --git a/spec/ruby/core/exception/fixtures/thread_fiber_ensure_non_root_fiber.rb b/spec/ruby/core/exception/fixtures/thread_fiber_ensure_non_root_fiber.rb new file mode 100644 index 0000000000..3364ed06d0 --- /dev/null +++ b/spec/ruby/core/exception/fixtures/thread_fiber_ensure_non_root_fiber.rb @@ -0,0 +1,25 @@ +ready = false +t = Thread.new do + f = Fiber.new do + begin + Fiber.yield + ensure + STDERR.puts "suspended fiber ensure" + end + end + f.resume + + f2 = Fiber.new do + begin + ready = true + sleep + ensure + STDERR.puts "current fiber ensure" + end + end + f2.resume +end + +Thread.pass until ready && t.stop? + +# let the program end, it's the same as #exit or an exception for this behavior diff --git a/spec/ruby/core/exception/top_level_spec.rb b/spec/ruby/core/exception/top_level_spec.rb index b47648425e..bcd09205b6 100644 --- a/spec/ruby/core/exception/top_level_spec.rb +++ b/spec/ruby/core/exception/top_level_spec.rb @@ -42,4 +42,16 @@ describe "An Exception reaching the top level" do EOS end end + + describe "kills all threads and fibers, ensure clauses are only run for threads current fibers, not for suspended fibers" do + it "with ensure on the root fiber" do + file = fixture(__FILE__, "thread_fiber_ensure.rb") + ruby_exe(file, args: "2>&1", exit_status: 0).should == "current fiber ensure\n" + end + + it "with ensure on non-root fiber" do + file = fixture(__FILE__, "thread_fiber_ensure_non_root_fiber.rb") + ruby_exe(file, args: "2>&1", exit_status: 0).should == "current fiber ensure\n" + end + end end diff --git a/spec/ruby/core/file/new_spec.rb b/spec/ruby/core/file/new_spec.rb index 004f78503a..a1ca46979e 100644 --- a/spec/ruby/core/file/new_spec.rb +++ b/spec/ruby/core/file/new_spec.rb @@ -78,6 +78,22 @@ describe "File.new" do File.should.exist?(@file) end + it "returns a new read-only File when mode is not specified" do + @fh = File.new(@file) + + -> { @fh.puts("test") }.should raise_error(IOError) + @fh.read.should == "" + File.should.exist?(@file) + end + + it "returns a new read-only File when mode is not specified but flags option is present" do + @fh = File.new(@file, flags: File::CREAT) + + -> { @fh.puts("test") }.should raise_error(IOError) + @fh.read.should == "" + File.should.exist?(@file) + end + it "creates a new file when use File::EXCL mode" do @fh = File.new(@file, File::EXCL) @fh.should be_kind_of(File) @@ -112,13 +128,32 @@ describe "File.new" do File.should.exist?(@file) end - it "creates a new file when use File::WRONLY|File::TRUNC mode" do @fh = File.new(@file, File::WRONLY|File::TRUNC) @fh.should be_kind_of(File) File.should.exist?(@file) end + it "returns a new read-only File when use File::RDONLY|File::CREAT mode" do + @fh = File.new(@file, File::RDONLY|File::CREAT) + @fh.should be_kind_of(File) + File.should.exist?(@file) + + # it's read-only + -> { @fh.puts("test") }.should raise_error(IOError) + @fh.read.should == "" + end + + it "returns a new read-only File when use File::CREAT mode" do + @fh = File.new(@file, File::CREAT) + @fh.should be_kind_of(File) + File.should.exist?(@file) + + # it's read-only + -> { @fh.puts("test") }.should raise_error(IOError) + @fh.read.should == "" + end + it "coerces filename using to_str" do name = mock("file") name.should_receive(:to_str).and_return(@file) @@ -133,6 +168,28 @@ describe "File.new" do File.should.exist?(@file) end + ruby_version_is "3.0" do + it "accepts options as a keyword argument" do + @fh = File.new(@file, 'w', 0755, flags: @flags) + @fh.should be_kind_of(File) + @fh.close + + -> { + @fh = File.new(@file, 'w', 0755, {flags: @flags}) + }.should raise_error(ArgumentError, "wrong number of arguments (given 4, expected 1..3)") + end + end + + it "bitwise-ORs mode and flags option" do + -> { + @fh = File.new(@file, 'w', flags: File::EXCL) + }.should raise_error(Errno::EEXIST, /File exists/) + + -> { + @fh = File.new(@file, mode: 'w', flags: File::EXCL) + }.should raise_error(Errno::EEXIST, /File exists/) + end + it "raises a TypeError if the first parameter can't be coerced to a string" do -> { File.new(true) }.should raise_error(TypeError) -> { File.new(false) }.should raise_error(TypeError) diff --git a/spec/ruby/core/file/open_spec.rb b/spec/ruby/core/file/open_spec.rb index 1729780570..0c6d6cd19c 100644 --- a/spec/ruby/core/file/open_spec.rb +++ b/spec/ruby/core/file/open_spec.rb @@ -565,6 +565,17 @@ describe "File.open" do File.open(@file, 'wb+') {|f| f.external_encoding.should == Encoding::BINARY} end + ruby_version_is "3.0" do + it "accepts options as a keyword argument" do + @fh = File.open(@file, 'w', 0755, flags: File::CREAT) + @fh.should be_an_instance_of(File) + + -> { + File.open(@file, 'w', 0755, {flags: File::CREAT}) + }.should raise_error(ArgumentError, "wrong number of arguments (given 4, expected 1..3)") + end + end + it "uses the second argument as an options Hash" do @fh = File.open(@file, mode: "r") @fh.should be_an_instance_of(File) diff --git a/spec/ruby/core/float/magnitude_spec.rb b/spec/ruby/core/float/magnitude_spec.rb index db577c15c5..7cdd8ef28a 100644 --- a/spec/ruby/core/float/magnitude_spec.rb +++ b/spec/ruby/core/float/magnitude_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../spec_helper" require_relative 'shared/abs' describe "Float#magnitude" do diff --git a/spec/ruby/core/io/initialize_spec.rb b/spec/ruby/core/io/initialize_spec.rb index ba5bc117b7..28fd7af7ab 100644 --- a/spec/ruby/core/io/initialize_spec.rb +++ b/spec/ruby/core/io/initialize_spec.rb @@ -27,6 +27,19 @@ describe "IO#initialize" do @io.fileno.should == fd end + ruby_version_is "3.0" do + it "accepts options as keyword arguments" do + fd = new_fd @name, "w:utf-8" + + @io.send(:initialize, fd, "w", flags: File::CREAT) + @io.fileno.should == fd + + -> { + @io.send(:initialize, fd, "w", {flags: File::CREAT}) + }.should raise_error(ArgumentError, "wrong number of arguments (given 3, expected 1..2)") + end + end + it "raises a TypeError when passed an IO" do -> { @io.send :initialize, STDOUT, 'w' }.should raise_error(TypeError) end diff --git a/spec/ruby/core/io/read_spec.rb b/spec/ruby/core/io/read_spec.rb index 529afbf0ff..e74012d027 100644 --- a/spec/ruby/core/io/read_spec.rb +++ b/spec/ruby/core/io/read_spec.rb @@ -23,6 +23,17 @@ describe "IO.read" do IO.read(p) end + ruby_version_is "3.0" do + # https://bugs.ruby-lang.org/issues/19354 + it "accepts options as keyword arguments" do + IO.read(@fname, 3, 0, mode: "r+").should == @contents[0, 3] + + -> { + IO.read(@fname, 3, 0, {mode: "r+"}) + }.should raise_error(ArgumentError, /wrong number of arguments/) + end + end + it "accepts an empty options Hash" do IO.read(@fname, **{}).should == @contents end @@ -55,6 +66,31 @@ describe "IO.read" do IO.read(@fname, mode: "a+").should == @contents end + platform_is_not :windows do + it "uses an :open_args option" do + string = IO.read(@fname, nil, 0, open_args: ["r", nil, {encoding: Encoding::US_ASCII}]) + string.encoding.should == Encoding::US_ASCII + + string = IO.read(@fname, nil, 0, open_args: ["r", nil, {}]) + string.encoding.should == Encoding::UTF_8 + end + end + + it "disregards other options if :open_args is given" do + string = IO.read(@fname,mode: "w", encoding: Encoding::UTF_32LE, open_args: ["r", encoding: Encoding::UTF_8]) + string.encoding.should == Encoding::UTF_8 + end + + it "doesn't require mode to be specified in :open_args" do + string = IO.read(@fname, nil, 0, open_args: [{encoding: Encoding::US_ASCII}]) + string.encoding.should == Encoding::US_ASCII + end + + it "doesn't require mode to be specified in :open_args even if flags option passed" do + string = IO.read(@fname, nil, 0, open_args: [{encoding: Encoding::US_ASCII, flags: File::CREAT}]) + string.encoding.should == Encoding::US_ASCII + end + it "treats second nil argument as no length limit" do IO.read(@fname, nil).should == @contents IO.read(@fname, nil, 5).should == IO.read(@fname, @contents.length, 5) diff --git a/spec/ruby/core/io/readlines_spec.rb b/spec/ruby/core/io/readlines_spec.rb index 496003002d..43d0750a72 100644 --- a/spec/ruby/core/io/readlines_spec.rb +++ b/spec/ruby/core/io/readlines_spec.rb @@ -127,6 +127,12 @@ describe "IO#readlines" do end end end + + describe "when passed arbitrary keyword argument" do + it "tolerates it" do + @io.readlines(chomp: true, foo: :bar).should == IOSpecs.lines_without_newline_characters + end + end end describe "IO#readlines" do diff --git a/spec/ruby/core/io/shared/binwrite.rb b/spec/ruby/core/io/shared/binwrite.rb index 3649bb47ff..950a6f51ab 100644 --- a/spec/ruby/core/io/shared/binwrite.rb +++ b/spec/ruby/core/io/shared/binwrite.rb @@ -21,6 +21,16 @@ describe :io_binwrite, shared: true do IO.send(@method, @filename, "abcde").should == 5 end + ruby_version_is "3.0" do + it "accepts options as a keyword argument" do + IO.send(@method, @filename, "hi", 0, flags: File::CREAT).should == 2 + + -> { + IO.send(@method, @filename, "hi", 0, {flags: File::CREAT}) + }.should raise_error(ArgumentError, "wrong number of arguments (given 4, expected 2..3)") + end + end + it "creates a file if missing" do fn = @filename + "xxx" begin @@ -67,6 +77,11 @@ describe :io_binwrite, shared: true do File.read(@filename).should == "\0\0foo" end + it "accepts a :flags option without :mode one" do + IO.send(@method, @filename, "hello, world!", flags: File::CREAT) + File.read(@filename).should == "hello, world!" + end + it "raises an error if readonly mode is specified" do -> { IO.send(@method, @filename, "abcde", mode: "r") }.should raise_error(IOError) end diff --git a/spec/ruby/core/io/shared/new.rb b/spec/ruby/core/io/shared/new.rb index 7677aada6e..da4c0af7a9 100644 --- a/spec/ruby/core/io/shared/new.rb +++ b/spec/ruby/core/io/shared/new.rb @@ -64,6 +64,17 @@ describe :io_new, shared: true do @io.should be_an_instance_of(IO) end + ruby_version_is "3.0" do + it "accepts options as keyword arguments" do + @io = IO.send(@method, @fd, "w", flags: File::CREAT) + @io.write("foo").should == 3 + + -> { + IO.send(@method, @fd, "w", {flags: File::CREAT}) + }.should raise_error(ArgumentError, "wrong number of arguments (given 3, expected 1..2)") + end + end + it "accepts a :mode option" do @io = IO.send(@method, @fd, mode: "w") @io.write("foo").should == 3 diff --git a/spec/ruby/core/io/write_spec.rb b/spec/ruby/core/io/write_spec.rb index bcc0582d9e..6e89c7cd9e 100644 --- a/spec/ruby/core/io/write_spec.rb +++ b/spec/ruby/core/io/write_spec.rb @@ -24,10 +24,6 @@ describe "IO#write on a file" do -> { @readonly_file.write("") }.should_not raise_error end - it "returns a length of 0 when writing a blank string" do - @file.write('').should == 0 - end - before :each do @external = Encoding.default_external @internal = Encoding.default_internal @@ -40,6 +36,18 @@ describe "IO#write on a file" do Encoding.default_internal = @internal end + it "returns a length of 0 when writing a blank string" do + @file.write('').should == 0 + end + + it "returns a length of 0 when writing blank strings" do + @file.write('', '', '').should == 0 + end + + it "returns a length of 0 when passed no arguments" do + @file.write().should == 0 + end + it "returns the number of bytes written" do @file.write("hellø").should == 6 end @@ -54,6 +62,18 @@ describe "IO#write on a file" do File.binread(@filename).bytes.should == [159] end + it "does not modify arguments when passed multiple arguments and external encoding not set" do + a, b = "a".freeze, "b".freeze + + File.open(@filename, "w") do |f| + f.write(a, b) + end + + File.binread(@filename).bytes.should == [97, 98] + a.encoding.should == Encoding::UTF_8 + b.encoding.should == Encoding::UTF_8 + end + it "uses the encoding from the given option for non-ascii encoding" do File.open(@filename, "w", encoding: Encoding::UTF_32LE) do |file| file.write("hi").should == 8 @@ -61,8 +81,25 @@ describe "IO#write on a file" do File.binread(@filename).should == "h\u0000\u0000\u0000i\u0000\u0000\u0000" end - it "uses an :open_args option" do - IO.write(@filename, 'hi', open_args: ["w", nil, {encoding: Encoding::UTF_32LE}]).should == 8 + it "uses the encoding from the given option for non-ascii encoding even if in binary mode" do + File.open(@filename, "w", encoding: Encoding::UTF_32LE, binmode: true) do |file| + file.should.binmode? + file.write("hi").should == 8 + end + File.binread(@filename).should == "h\u0000\u0000\u0000i\u0000\u0000\u0000" + + File.open(@filename, "wb", encoding: Encoding::UTF_32LE) do |file| + file.should.binmode? + file.write("hi").should == 8 + end + File.binread(@filename).should == "h\u0000\u0000\u0000i\u0000\u0000\u0000" + end + + it "uses the encoding from the given option for non-ascii encoding when multiple arguments passes" do + File.open(@filename, "w", encoding: Encoding::UTF_32LE) do |file| + file.write("h", "i").should == 8 + end + File.binread(@filename).should == "h\u0000\u0000\u0000i\u0000\u0000\u0000" end it "raises a invalid byte sequence error if invalid bytes are being written" do @@ -82,6 +119,20 @@ describe "IO#write on a file" do res = "H#{ë}ll#{ö}" File.binread(@filename).should == res.force_encoding(Encoding::BINARY) end + + platform_is_not :windows do + it "writes binary data if no encoding is given and multiple arguments passed" do + File.open(@filename, "w") do |file| + file.write("\x87".b, "ą") # 0x87 isn't a valid UTF-8 binary representation of a character + end + File.binread(@filename).bytes.should == [0x87, 0xC4, 0x85] + + File.open(@filename, "w") do |file| + file.write("\x61".encode("utf-32le"), "ą") + end + File.binread(@filename).bytes.should == [0x61, 0x00, 0x00, 0x00, 0xC4, 0x85] + end + end end describe "IO.write" do @@ -96,10 +147,38 @@ describe "IO.write" do File.read(@filename).should == "\0\0hi" end + it "requires mode to be specified in :open_args" do + -> { + IO.write(@filename, 'hi', open_args: [{encoding: Encoding::UTF_32LE, binmode: true}]) + }.should raise_error(IOError, "not opened for writing") + + IO.write(@filename, 'hi', open_args: ["w", {encoding: Encoding::UTF_32LE, binmode: true}]).should == 8 + IO.write(@filename, 'hi', open_args: [{encoding: Encoding::UTF_32LE, binmode: true, mode: "w"}]).should == 8 + end + + it "requires mode to be specified in :open_args even if flags option passed" do + -> { + IO.write(@filename, 'hi', open_args: [{encoding: Encoding::UTF_32LE, binmode: true, flags: File::CREAT}]) + }.should raise_error(IOError, "not opened for writing") + + IO.write(@filename, 'hi', open_args: ["w", {encoding: Encoding::UTF_32LE, binmode: true, flags: File::CREAT}]).should == 8 + IO.write(@filename, 'hi', open_args: [{encoding: Encoding::UTF_32LE, binmode: true, flags: File::CREAT, mode: "w"}]).should == 8 + end + it "uses the given encoding and returns the number of bytes written" do IO.write(@filename, 'hi', mode: "w", encoding: Encoding::UTF_32LE).should == 8 end + it "raises ArgumentError if encoding is specified in mode parameter and is given as :encoding option" do + -> { + IO.write(@filename, 'hi', mode: "w:UTF-16LE:UTF-16BE", encoding: Encoding::UTF_32LE) + }.should raise_error(ArgumentError, "encoding specified twice") + + -> { + IO.write(@filename, 'hi', mode: "w:UTF-16BE", encoding: Encoding::UTF_32LE) + }.should raise_error(ArgumentError, "encoding specified twice") + end + it "writes the file with the permissions in the :perm parameter" do rm_r @filename IO.write(@filename, 'write :perm spec', mode: "w", perm: 0o755).should == 16 diff --git a/spec/ruby/core/kernel/Integer_spec.rb b/spec/ruby/core/kernel/Integer_spec.rb index 2c78e27428..c691cb4c41 100644 --- a/spec/ruby/core/kernel/Integer_spec.rb +++ b/spec/ruby/core/kernel/Integer_spec.rb @@ -573,10 +573,17 @@ describe "Integer() given a String and base", shared: true do -> { Integer("0#{d}1", base) }.should raise_error(ArgumentError) end end + end - it "raises an ArgumentError if a base is given for a non-String value" do - -> { Integer(98, 15) }.should raise_error(ArgumentError) - end + it "raises an ArgumentError if a base is given for a non-String value" do + -> { Integer(98, 15) }.should raise_error(ArgumentError) + end + + it "tries to convert the base to an integer using to_int" do + obj = mock('8') + obj.should_receive(:to_int).and_return(8) + + Integer("777", obj).should == 0777 end describe "when passed exception: false" do diff --git a/spec/ruby/core/kernel/at_exit_spec.rb b/spec/ruby/core/kernel/at_exit_spec.rb index a784c1ae17..ebd9a71d15 100644 --- a/spec/ruby/core/kernel/at_exit_spec.rb +++ b/spec/ruby/core/kernel/at_exit_spec.rb @@ -1,67 +1,16 @@ require_relative '../../spec_helper' require_relative 'fixtures/classes' +require_relative '../../shared/kernel/at_exit' describe "Kernel.at_exit" do + it_behaves_like :kernel_at_exit, :at_exit + it "is a private method" do Kernel.should have_private_instance_method(:at_exit) end - it "runs after all other code" do - ruby_exe("at_exit {print 5}; print 6").should == "65" - end - - it "runs in reverse order of registration" do - code = "at_exit {print 4};at_exit {print 5}; print 6; at_exit {print 7}" - ruby_exe(code).should == "6754" - end - - it "allows calling exit inside at_exit handler" do - code = "at_exit {print 3}; at_exit {print 4; exit; print 5}; at_exit {print 6}" - ruby_exe(code).should == "643" - end - - it "gives access to the last raised exception" do - code = <<-EOC - at_exit do - puts "The exception matches: \#{$! == $exception} (message=\#{$!.message})" - end - - begin - raise "foo" - rescue => $exception - raise - end - EOC - - result = ruby_exe(code, args: "2>&1", exit_status: 1) - result.lines.should.include?("The exception matches: true (message=foo)\n") - end - - it "both exceptions in at_exit and in the main script are printed" do - code = 'at_exit { raise "at_exit_error" }; raise "main_script_error"' - result = ruby_exe(code, args: "2>&1", exit_status: 1) - result.should.include?('at_exit_error (RuntimeError)') - result.should.include?('main_script_error (RuntimeError)') - end - - it "decides the exit status if both at_exit and the main script raise SystemExit" do - ruby_exe('at_exit { exit 43 }; exit 42', args: "2>&1", exit_status: 43) - $?.exitstatus.should == 43 - end - - it "runs all at_exit even if some raise exceptions" do - code = 'at_exit { STDERR.puts "last" }; at_exit { exit 43 }; at_exit { STDERR.puts "first" }; exit 42' - result = ruby_exe(code, args: "2>&1", exit_status: 43) - result.should == "first\nlast\n" - $?.exitstatus.should == 43 - end - - it "runs at_exit handlers even if the main script fails to parse" do - script = fixture(__FILE__, "at_exit.rb") - result = ruby_exe('{', options: "-r#{script}", args: "2>&1", exit_status: 1) - $?.should_not.success? - result.should.include?("at_exit ran\n") - result.should.include?("syntax error") + it "raises ArgumentError if called without a block" do + -> { at_exit }.should raise_error(ArgumentError, "called without a block") end end diff --git a/spec/ruby/core/kernel/exit_spec.rb b/spec/ruby/core/kernel/exit_spec.rb index f168cb375e..93cec3fee5 100644 --- a/spec/ruby/core/kernel/exit_spec.rb +++ b/spec/ruby/core/kernel/exit_spec.rb @@ -10,6 +10,10 @@ describe "Kernel#exit" do it_behaves_like :process_exit, :exit, KernelSpecs::Method.new end +describe "Kernel.exit" do + it_behaves_like :process_exit, :exit, Kernel +end + describe "Kernel#exit!" do it "is a private method" do Kernel.should have_private_instance_method(:exit!) @@ -18,10 +22,6 @@ describe "Kernel#exit!" do it_behaves_like :process_exit!, :exit!, "self" end -describe "Kernel.exit" do - it_behaves_like :process_exit, :exit, Kernel -end - describe "Kernel.exit!" do - it_behaves_like :process_exit!, :exit!, Kernel + it_behaves_like :process_exit!, :exit!, "Kernel" end diff --git a/spec/ruby/core/kernel/fixtures/at_exit.rb b/spec/ruby/core/kernel/fixtures/at_exit.rb deleted file mode 100644 index 9c11a7ad6c..0000000000 --- a/spec/ruby/core/kernel/fixtures/at_exit.rb +++ /dev/null @@ -1,3 +0,0 @@ -at_exit do - STDERR.puts "at_exit ran" -end diff --git a/spec/ruby/core/kernel/open_spec.rb b/spec/ruby/core/kernel/open_spec.rb index fa9299f9d4..bad2ae9d2c 100644 --- a/spec/ruby/core/kernel/open_spec.rb +++ b/spec/ruby/core/kernel/open_spec.rb @@ -72,6 +72,17 @@ describe "Kernel#open" do -> { open }.should raise_error(ArgumentError) end + ruby_version_is "3.0" do + it "accepts options as keyword arguments" do + @file = open(@name, "r", 0666, flags: File::CREAT) + @file.should be_kind_of(File) + + -> { + open(@name, "r", 0666, {flags: File::CREAT}) + }.should raise_error(ArgumentError, "wrong number of arguments (given 4, expected 1..3)") + end + end + describe "when given an object that responds to to_open" do before :each do ScratchPad.clear @@ -109,11 +120,21 @@ describe "Kernel#open" do it "passes its arguments onto #to_open" do obj = mock('to_open') - obj.should_receive(:to_open).with(1,2,3) - + obj.should_receive(:to_open).with(1, 2, 3) open(obj, 1, 2, 3) end + it "passes keyword arguments onto #to_open as keyword arguments if to_open accepts them" do + obj = Object.new + def obj.to_open(*args, **kw) + ScratchPad << {args: args, kw: kw} + end + + ScratchPad.record [] + open(obj, 1, 2, 3, a: "b") + ScratchPad.recorded.should == [args: [1, 2, 3], kw: {a: "b"}] + end + it "passes the return value from #to_open to a block" do obj = mock('to_open') obj.should_receive(:to_open).and_return(:value) diff --git a/spec/ruby/core/kernel/singleton_class_spec.rb b/spec/ruby/core/kernel/singleton_class_spec.rb index c56fa08cc1..4865e29c10 100644 --- a/spec/ruby/core/kernel/singleton_class_spec.rb +++ b/spec/ruby/core/kernel/singleton_class_spec.rb @@ -20,10 +20,26 @@ describe "Kernel#singleton_class" do end it "raises TypeError for Integer" do - -> { 123.singleton_class }.should raise_error(TypeError) + -> { 123.singleton_class }.should raise_error(TypeError, "can't define singleton") + end + + it "raises TypeError for Float" do + -> { 3.14.singleton_class }.should raise_error(TypeError, "can't define singleton") end it "raises TypeError for Symbol" do - -> { :foo.singleton_class }.should raise_error(TypeError) + -> { :foo.singleton_class }.should raise_error(TypeError, "can't define singleton") + end + + it "raises TypeError for a frozen deduplicated String" do + -> { (-"string").singleton_class }.should raise_error(TypeError, "can't define singleton") + -> { a = -"string"; a.singleton_class }.should raise_error(TypeError, "can't define singleton") + -> { a = "string"; (-a).singleton_class }.should raise_error(TypeError, "can't define singleton") + end + + it "returns a frozen singleton class if object is frozen" do + obj = Object.new + obj.freeze + obj.singleton_class.frozen?.should be_true end end diff --git a/spec/ruby/core/marshal/shared/load.rb b/spec/ruby/core/marshal/shared/load.rb index 1df2e8d4f1..08261e65d7 100644 --- a/spec/ruby/core/marshal/shared/load.rb +++ b/spec/ruby/core/marshal/shared/load.rb @@ -8,7 +8,11 @@ describe :marshal_load, shared: true do it "raises an ArgumentError when the dumped data is truncated" do obj = {first: 1, second: 2, third: 3} - -> { Marshal.send(@method, Marshal.dump(obj)[0, 5]) }.should raise_error(ArgumentError) + -> { Marshal.send(@method, Marshal.dump(obj)[0, 5]) }.should raise_error(ArgumentError, "marshal data too short") + end + + it "raises an ArgumentError when the argument is empty String" do + -> { Marshal.send(@method, "") }.should raise_error(ArgumentError, "marshal data too short") end it "raises an ArgumentError when the dumped class is missing" do diff --git a/spec/ruby/core/module/const_source_location_spec.rb b/spec/ruby/core/module/const_source_location_spec.rb index 11a2e74756..145b069e2e 100644 --- a/spec/ruby/core/module/const_source_location_spec.rb +++ b/spec/ruby/core/module/const_source_location_spec.rb @@ -67,6 +67,11 @@ describe "Module#const_source_location" do end describe "with statically assigned constants" do + it "works for the module and class keywords" do + ConstantSpecs.const_source_location(:ModuleB).should == [@constants_fixture_path, ConstantSpecs::ModuleB::LINE] + ConstantSpecs.const_source_location(:ClassA).should == [@constants_fixture_path, ConstantSpecs::ClassA::LINE] + end + it "searches location path the immediate class or module first" do ConstantSpecs::ClassA.const_source_location(:CS_CONST10).should == [@constants_fixture_path, ConstantSpecs::ClassA::CS_CONST10_LINE] ConstantSpecs::ModuleA.const_source_location(:CS_CONST10).should == [@constants_fixture_path, ConstantSpecs::ModuleA::CS_CONST10_LINE] @@ -133,7 +138,7 @@ describe "Module#const_source_location" do it "calls #to_str to convert the given name to a String" do name = mock("ClassA") name.should_receive(:to_str).and_return("ClassA") - ConstantSpecs.const_source_location(name).should == [@constants_fixture_path, ConstantSpecs::ClassA::CS_CLASS_A_LINE] + ConstantSpecs.const_source_location(name).should == [@constants_fixture_path, ConstantSpecs::ClassA::LINE] end it "raises a TypeError if conversion to a String by calling #to_str fails" do diff --git a/spec/ruby/core/module/method_added_spec.rb b/spec/ruby/core/module/method_added_spec.rb index b983c8da76..ec92cddc1e 100644 --- a/spec/ruby/core/module/method_added_spec.rb +++ b/spec/ruby/core/module/method_added_spec.rb @@ -2,6 +2,10 @@ require_relative '../../spec_helper' require_relative 'fixtures/classes' describe "Module#method_added" do + before :each do + ScratchPad.record [] + end + it "is a private instance method" do Module.should have_private_instance_method(:method_added) end @@ -13,8 +17,6 @@ describe "Module#method_added" do end it "is called when a new instance method is defined in self" do - ScratchPad.record [] - Module.new do def self.method_added(name) ScratchPad << name @@ -32,8 +34,6 @@ describe "Module#method_added" do it "is not called when a singleton method is added" do # obj.singleton_method_added is called instead - ScratchPad.record [] - klass = Class.new def klass.method_added(name) ScratchPad << name @@ -60,8 +60,71 @@ describe "Module#method_added" do m.should_not have_method(:method_to_undef) end + it "is not called when a method changes visibility" do + Module.new do + def public_method + end + + def private_method + end + + def self.method_added(name) + ScratchPad << name + end + + public :public_method + private :public_method + + private :private_method + public :private_method + end + + ScratchPad.recorded.should == [] + end + + it "is called when using #private in a subclass" do + parent = Class.new do + def foo + end + end + + Class.new(parent) do + def self.method_added(name) + ScratchPad << name + end + + # Create an instance as that might initialize some method lookup caches, which is interesting to test + self.new.foo + + private :foo + public :foo + end + + ScratchPad.recorded.should == [:foo] + end + + it "is not called when a method is copied via module_function, rather #singleton_method_added is called" do + Module.new do + def mod_function + end + + def self.method_added(name) + ScratchPad << [:method_added, name] + end + + def self.singleton_method_added(name) + ScratchPad << [:singleton_method_added, name] + end + + ScratchPad.record [] + + module_function :mod_function + end + + ScratchPad.recorded.should == [[:singleton_method_added, :mod_function]] + end + it "is called with a precise caller location with the line of the 'def'" do - ScratchPad.record [] line = nil Module.new do diff --git a/spec/ruby/core/numeric/magnitude_spec.rb b/spec/ruby/core/numeric/magnitude_spec.rb index 7a3290b036..1371dff21f 100644 --- a/spec/ruby/core/numeric/magnitude_spec.rb +++ b/spec/ruby/core/numeric/magnitude_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../spec_helper" require_relative 'shared/abs' describe "Numeric#magnitude" do diff --git a/spec/ruby/core/process/exit_spec.rb b/spec/ruby/core/process/exit_spec.rb index 70d79d789d..4f7dc94407 100644 --- a/spec/ruby/core/process/exit_spec.rb +++ b/spec/ruby/core/process/exit_spec.rb @@ -6,5 +6,5 @@ describe "Process.exit" do end describe "Process.exit!" do - it_behaves_like :process_exit!, :exit!, Process + it_behaves_like :process_exit!, :exit!, "Process" end diff --git a/spec/ruby/core/random/new_spec.rb b/spec/ruby/core/random/new_spec.rb index 4280b5b9c3..90e2a9d6f2 100644 --- a/spec/ruby/core/random/new_spec.rb +++ b/spec/ruby/core/random/new_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../spec_helper" describe "Random.new" do it "returns a new instance of Random" do Random.new.should be_an_instance_of(Random) diff --git a/spec/ruby/core/range/step_spec.rb b/spec/ruby/core/range/step_spec.rb index 61ddc5205d..9024636d55 100644 --- a/spec/ruby/core/range/step_spec.rb +++ b/spec/ruby/core/range/step_spec.rb @@ -474,10 +474,14 @@ describe "Range#step" do end end + # We use .take below to ensure the enumerator works + # because that's an Enumerable method and so it uses the Enumerator behavior + # not just a method overridden in Enumerator::ArithmeticSequence. describe "type" do context "when both begin and end are numerics" do it "returns an instance of Enumerator::ArithmeticSequence" do (1..10).step.class.should == Enumerator::ArithmeticSequence + (1..10).step(3).take(4).should == [1, 4, 7, 10] end end @@ -490,10 +494,12 @@ describe "Range#step" do context "when range is endless" do it "returns an instance of Enumerator::ArithmeticSequence when begin is numeric" do (1..).step.class.should == Enumerator::ArithmeticSequence + (1..).step(2).take(3).should == [1, 3, 5] end it "returns an instance of Enumerator when begin is not numeric" do ("a"..).step.class.should == Enumerator + ("a"..).step(2).take(3).should == %w[a c e] end end @@ -506,6 +512,7 @@ describe "Range#step" do context "when begin and end are not numerics" do it "returns an instance of Enumerator" do ("a".."z").step.class.should == Enumerator + ("a".."z").step(3).take(4).should == %w[a d g j] end end end diff --git a/spec/ruby/core/rational/abs_spec.rb b/spec/ruby/core/rational/abs_spec.rb index aed7713058..7272ad2422 100644 --- a/spec/ruby/core/rational/abs_spec.rb +++ b/spec/ruby/core/rational/abs_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../spec_helper" require_relative '../../shared/rational/abs' describe "Rational#abs" do diff --git a/spec/ruby/core/rational/ceil_spec.rb b/spec/ruby/core/rational/ceil_spec.rb index 5b0ca4a9d6..e736351604 100644 --- a/spec/ruby/core/rational/ceil_spec.rb +++ b/spec/ruby/core/rational/ceil_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../spec_helper" require_relative '../../shared/rational/ceil' describe "Rational#ceil" do diff --git a/spec/ruby/core/rational/coerce_spec.rb b/spec/ruby/core/rational/coerce_spec.rb index 3f78f0bcd6..9c0f05829b 100644 --- a/spec/ruby/core/rational/coerce_spec.rb +++ b/spec/ruby/core/rational/coerce_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../spec_helper" require_relative '../../shared/rational/coerce' describe "Rational#coerce" do diff --git a/spec/ruby/core/rational/comparison_spec.rb b/spec/ruby/core/rational/comparison_spec.rb index 9d8e7fd7ee..877069fb8f 100644 --- a/spec/ruby/core/rational/comparison_spec.rb +++ b/spec/ruby/core/rational/comparison_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../spec_helper" require_relative '../../shared/rational/comparison' describe "Rational#<=> when passed a Rational object" do diff --git a/spec/ruby/core/rational/denominator_spec.rb b/spec/ruby/core/rational/denominator_spec.rb index 6214b40587..c2f49b4190 100644 --- a/spec/ruby/core/rational/denominator_spec.rb +++ b/spec/ruby/core/rational/denominator_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../spec_helper" require_relative '../../shared/rational/denominator' describe "Rational#denominator" do diff --git a/spec/ruby/core/rational/div_spec.rb b/spec/ruby/core/rational/div_spec.rb index 1cd8606b90..bee7d01a67 100644 --- a/spec/ruby/core/rational/div_spec.rb +++ b/spec/ruby/core/rational/div_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../spec_helper" require_relative '../../shared/rational/div' describe "Rational#div" do diff --git a/spec/ruby/core/rational/divide_spec.rb b/spec/ruby/core/rational/divide_spec.rb index d8e3a44dc2..14e8c4c195 100644 --- a/spec/ruby/core/rational/divide_spec.rb +++ b/spec/ruby/core/rational/divide_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../spec_helper" require_relative '../../shared/rational/divide' require_relative '../../shared/rational/arithmetic_exception_in_coerce' diff --git a/spec/ruby/core/rational/divmod_spec.rb b/spec/ruby/core/rational/divmod_spec.rb index 6be1f8bd73..7ffdde74f4 100644 --- a/spec/ruby/core/rational/divmod_spec.rb +++ b/spec/ruby/core/rational/divmod_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../spec_helper" require_relative '../../shared/rational/divmod' describe "Rational#divmod when passed a Rational" do diff --git a/spec/ruby/core/rational/equal_value_spec.rb b/spec/ruby/core/rational/equal_value_spec.rb index 8e7acb1354..c6f7f4c6a2 100644 --- a/spec/ruby/core/rational/equal_value_spec.rb +++ b/spec/ruby/core/rational/equal_value_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../spec_helper" require_relative '../../shared/rational/equal_value' describe "Rational#==" do diff --git a/spec/ruby/core/rational/exponent_spec.rb b/spec/ruby/core/rational/exponent_spec.rb index 622cf22782..7e35b4ebc1 100644 --- a/spec/ruby/core/rational/exponent_spec.rb +++ b/spec/ruby/core/rational/exponent_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../spec_helper" require_relative '../../shared/rational/exponent' describe "Rational#**" do diff --git a/spec/ruby/core/rational/fdiv_spec.rb b/spec/ruby/core/rational/fdiv_spec.rb index bfb321abaa..b75f39abd5 100644 --- a/spec/ruby/core/rational/fdiv_spec.rb +++ b/spec/ruby/core/rational/fdiv_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../spec_helper" require_relative '../../shared/rational/fdiv' describe "Rational#fdiv" do diff --git a/spec/ruby/core/rational/floor_spec.rb b/spec/ruby/core/rational/floor_spec.rb index 752a2d8815..70db0499d0 100644 --- a/spec/ruby/core/rational/floor_spec.rb +++ b/spec/ruby/core/rational/floor_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../spec_helper" require_relative '../../shared/rational/floor' describe "Rational#floor" do diff --git a/spec/ruby/core/rational/hash_spec.rb b/spec/ruby/core/rational/hash_spec.rb index 84cd31518a..7e8d30049b 100644 --- a/spec/ruby/core/rational/hash_spec.rb +++ b/spec/ruby/core/rational/hash_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../spec_helper" require_relative '../../shared/rational/hash' describe "Rational#hash" do diff --git a/spec/ruby/core/rational/inspect_spec.rb b/spec/ruby/core/rational/inspect_spec.rb index ef337ef0ce..2cbf6cadc1 100644 --- a/spec/ruby/core/rational/inspect_spec.rb +++ b/spec/ruby/core/rational/inspect_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../spec_helper" require_relative '../../shared/rational/inspect' describe "Rational#inspect" do diff --git a/spec/ruby/core/rational/integer_spec.rb b/spec/ruby/core/rational/integer_spec.rb index 0f9a3bdead..be7476a9dd 100644 --- a/spec/ruby/core/rational/integer_spec.rb +++ b/spec/ruby/core/rational/integer_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../spec_helper" describe "Rational#integer?" do # Guard against the Mathn library guard -> { !defined?(Math.rsqrt) } do diff --git a/spec/ruby/core/rational/magnitude_spec.rb b/spec/ruby/core/rational/magnitude_spec.rb index 878fc8f879..27d9af6a81 100644 --- a/spec/ruby/core/rational/magnitude_spec.rb +++ b/spec/ruby/core/rational/magnitude_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../spec_helper" require_relative '../../shared/rational/abs' describe "Rational#abs" do diff --git a/spec/ruby/core/rational/modulo_spec.rb b/spec/ruby/core/rational/modulo_spec.rb index c43f7788e3..7a60c176ac 100644 --- a/spec/ruby/core/rational/modulo_spec.rb +++ b/spec/ruby/core/rational/modulo_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../spec_helper" require_relative '../../shared/rational/modulo' describe "Rational#%" do diff --git a/spec/ruby/core/rational/multiply_spec.rb b/spec/ruby/core/rational/multiply_spec.rb index ea644074e9..7413376bb1 100644 --- a/spec/ruby/core/rational/multiply_spec.rb +++ b/spec/ruby/core/rational/multiply_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../spec_helper" require_relative '../../shared/rational/multiply' require_relative '../../shared/rational/arithmetic_exception_in_coerce' diff --git a/spec/ruby/core/rational/numerator_spec.rb b/spec/ruby/core/rational/numerator_spec.rb index 85b2ed9e86..6f9a9c0e3b 100644 --- a/spec/ruby/core/rational/numerator_spec.rb +++ b/spec/ruby/core/rational/numerator_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../spec_helper" require_relative '../../shared/rational/numerator' describe "Rational#numerator" do diff --git a/spec/ruby/core/rational/plus_spec.rb b/spec/ruby/core/rational/plus_spec.rb index e7ef3a8f92..67c0ff63d2 100644 --- a/spec/ruby/core/rational/plus_spec.rb +++ b/spec/ruby/core/rational/plus_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../spec_helper" require_relative '../../shared/rational/plus' require_relative '../../shared/rational/arithmetic_exception_in_coerce' diff --git a/spec/ruby/core/rational/quo_spec.rb b/spec/ruby/core/rational/quo_spec.rb index 119aca1955..181f091f7c 100644 --- a/spec/ruby/core/rational/quo_spec.rb +++ b/spec/ruby/core/rational/quo_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../spec_helper" require_relative '../../shared/rational/divide' describe "Rational#quo" do diff --git a/spec/ruby/core/rational/remainder_spec.rb b/spec/ruby/core/rational/remainder_spec.rb index 0f9442f6f5..1c0035e5f4 100644 --- a/spec/ruby/core/rational/remainder_spec.rb +++ b/spec/ruby/core/rational/remainder_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../spec_helper" require_relative '../../shared/rational/remainder' describe "Rational#remainder" do diff --git a/spec/ruby/core/rational/to_f_spec.rb b/spec/ruby/core/rational/to_f_spec.rb index 15bf1e88dc..a9cd1be3b5 100644 --- a/spec/ruby/core/rational/to_f_spec.rb +++ b/spec/ruby/core/rational/to_f_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../spec_helper" require_relative '../../shared/rational/to_f' describe "Rational#to_f" do diff --git a/spec/ruby/core/rational/to_i_spec.rb b/spec/ruby/core/rational/to_i_spec.rb index 3deb3664e1..22cf02b4da 100644 --- a/spec/ruby/core/rational/to_i_spec.rb +++ b/spec/ruby/core/rational/to_i_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../spec_helper" require_relative '../../shared/rational/to_i' describe "Rational#to_i" do diff --git a/spec/ruby/core/rational/to_r_spec.rb b/spec/ruby/core/rational/to_r_spec.rb index cc704c965e..03f204daf1 100644 --- a/spec/ruby/core/rational/to_r_spec.rb +++ b/spec/ruby/core/rational/to_r_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../spec_helper" require_relative '../../shared/rational/to_r' describe "Rational#to_r" do diff --git a/spec/ruby/core/rational/to_s_spec.rb b/spec/ruby/core/rational/to_s_spec.rb index c5c419787c..5d90c7d80b 100644 --- a/spec/ruby/core/rational/to_s_spec.rb +++ b/spec/ruby/core/rational/to_s_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../spec_helper" require_relative '../../shared/rational/to_s' describe "Rational#to_s" do diff --git a/spec/ruby/core/rational/truncate_spec.rb b/spec/ruby/core/rational/truncate_spec.rb index 4e72339752..47a7cdf17c 100644 --- a/spec/ruby/core/rational/truncate_spec.rb +++ b/spec/ruby/core/rational/truncate_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../spec_helper" require_relative '../../shared/rational/truncate' describe "Rational#truncate" do diff --git a/spec/ruby/core/rational/zero_spec.rb b/spec/ruby/core/rational/zero_spec.rb index e6dd751922..af7fb391ac 100644 --- a/spec/ruby/core/rational/zero_spec.rb +++ b/spec/ruby/core/rational/zero_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../spec_helper" describe "Rational#zero?" do it "returns true if the numerator is 0" do Rational(0,26).zero?.should be_true diff --git a/spec/ruby/core/string/casecmp_spec.rb b/spec/ruby/core/string/casecmp_spec.rb index 986fbc8718..81ebea557c 100644 --- a/spec/ruby/core/string/casecmp_spec.rb +++ b/spec/ruby/core/string/casecmp_spec.rb @@ -117,6 +117,11 @@ describe "String#casecmp independent of case" do "B".casecmp(a).should == 1 end end + + it "returns 0 for empty strings in different encodings" do + ''.b.casecmp('').should == 0 + ''.b.casecmp(''.encode("UTF-32LE")).should == 0 + end end describe 'String#casecmp? independent of case' do @@ -191,4 +196,9 @@ describe 'String#casecmp? independent of case' do it "returns nil if other can't be converted to a string" do "abc".casecmp?(mock('abc')).should be_nil end + + it "returns true for empty strings in different encodings" do + ''.b.should.casecmp?('') + ''.b.should.casecmp?(''.encode("UTF-32LE")) + end end diff --git a/spec/ruby/core/string/chars_spec.rb b/spec/ruby/core/string/chars_spec.rb index 715e65dc90..ee85430574 100644 --- a/spec/ruby/core/string/chars_spec.rb +++ b/spec/ruby/core/string/chars_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../spec_helper" require_relative 'shared/chars' describe "String#chars" do diff --git a/spec/ruby/core/string/each_char_spec.rb b/spec/ruby/core/string/each_char_spec.rb index aff98c0a5c..36219f79db 100644 --- a/spec/ruby/core/string/each_char_spec.rb +++ b/spec/ruby/core/string/each_char_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../spec_helper" require_relative 'shared/chars' require_relative 'shared/each_char_without_block' diff --git a/spec/ruby/core/string/each_grapheme_cluster_spec.rb b/spec/ruby/core/string/each_grapheme_cluster_spec.rb index b45d89ecb0..f28e24000e 100644 --- a/spec/ruby/core/string/each_grapheme_cluster_spec.rb +++ b/spec/ruby/core/string/each_grapheme_cluster_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../spec_helper" require_relative 'shared/chars' require_relative 'shared/grapheme_clusters' require_relative 'shared/each_char_without_block' diff --git a/spec/ruby/core/string/grapheme_clusters_spec.rb b/spec/ruby/core/string/grapheme_clusters_spec.rb index 3046265a12..380a245083 100644 --- a/spec/ruby/core/string/grapheme_clusters_spec.rb +++ b/spec/ruby/core/string/grapheme_clusters_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../spec_helper" require_relative 'shared/chars' require_relative 'shared/grapheme_clusters' diff --git a/spec/ruby/core/string/shared/to_sym.rb b/spec/ruby/core/string/shared/to_sym.rb index ef7c22bb6a..52d8314211 100644 --- a/spec/ruby/core/string/shared/to_sym.rb +++ b/spec/ruby/core/string/shared/to_sym.rb @@ -67,6 +67,6 @@ describe :string_to_sym, shared: true do invalid_utf8.should_not.valid_encoding? -> { invalid_utf8.send(@method) - }.should raise_error(EncodingError, /invalid/) + }.should raise_error(EncodingError, 'invalid symbol in encoding UTF-8 :"\xC3"') end end diff --git a/spec/ruby/core/struct/deconstruct_keys_spec.rb b/spec/ruby/core/struct/deconstruct_keys_spec.rb index 088803d028..b4c84c49df 100644 --- a/spec/ruby/core/struct/deconstruct_keys_spec.rb +++ b/spec/ruby/core/struct/deconstruct_keys_spec.rb @@ -64,7 +64,7 @@ describe "Struct#deconstruct_keys" do obj.deconstruct_keys(nil).should == {x: 1, y: 2} end - it "raise TypeError if passed anything accept nil or array" do + it "raise TypeError if passed anything except nil or array" do struct = Struct.new(:x, :y) s = struct.new(1, 2) diff --git a/spec/ruby/core/struct/initialize_spec.rb b/spec/ruby/core/struct/initialize_spec.rb index cfb302209e..a5ebe9551c 100644 --- a/spec/ruby/core/struct/initialize_spec.rb +++ b/spec/ruby/core/struct/initialize_spec.rb @@ -48,4 +48,14 @@ describe "Struct#initialize" do }.should complain(/warning: Passing only keyword arguments/) end end + + ruby_version_is "3.2" do + it "can be initialized with keyword arguments" do + positional_args = StructClasses::Ruby.new("3.2", "OS") + keyword_args = StructClasses::Ruby.new(version: "3.2", platform: "OS") + + positional_args.version.should == keyword_args.version + positional_args.platform.should == keyword_args.platform + end + end end diff --git a/spec/ruby/core/struct/inspect_spec.rb b/spec/ruby/core/struct/inspect_spec.rb index 83e13597ba..657b06abc1 100644 --- a/spec/ruby/core/struct/inspect_spec.rb +++ b/spec/ruby/core/struct/inspect_spec.rb @@ -3,10 +3,5 @@ require_relative 'fixtures/classes' require_relative 'shared/inspect' describe "Struct#inspect" do - it "returns a string representation showing members and values" do - car = StructClasses::Car.new('Ford', 'Ranger') - car.inspect.should == '#' - end - it_behaves_like :struct_inspect, :inspect end diff --git a/spec/ruby/core/struct/shared/inspect.rb b/spec/ruby/core/struct/shared/inspect.rb index 90594a5452..e65a4fb45d 100644 --- a/spec/ruby/core/struct/shared/inspect.rb +++ b/spec/ruby/core/struct/shared/inspect.rb @@ -1,5 +1,28 @@ describe :struct_inspect, shared: true do + it "returns a string representation showing members and values" do + car = StructClasses::Car.new('Ford', 'Ranger') + car.send(@method).should == '#' + end + it "returns a string representation without the class name for anonymous structs" do Struct.new(:a).new("").send(@method).should == '#' end + + it "returns a string representation without the class name for structs nested in anonymous classes" do + c = Class.new + c.class_eval <<~DOC + class Foo < Struct.new(:a); end + DOC + + c::Foo.new("").send(@method).should == '#' + end + + it "returns a string representation without the class name for structs nested in anonymous modules" do + m = Module.new + m.module_eval <<~DOC + class Foo < Struct.new(:a); end + DOC + + m::Foo.new("").send(@method).should == '#' + end end diff --git a/spec/ruby/core/symbol/casecmp_spec.rb b/spec/ruby/core/symbol/casecmp_spec.rb index 80ea51e910..662a29a284 100644 --- a/spec/ruby/core/symbol/casecmp_spec.rb +++ b/spec/ruby/core/symbol/casecmp_spec.rb @@ -56,6 +56,10 @@ describe "Symbol#casecmp with Symbol" do lower_a_tilde.casecmp(upper_a_tilde).should == 1 lower_a_umlaut.casecmp(upper_a_umlaut).should == 1 end + + it "returns 0 for empty strings in different encodings" do + ''.to_sym.casecmp(''.encode("UTF-32LE").to_sym).should == 0 + end end describe "Symbol#casecmp" do @@ -141,4 +145,8 @@ describe 'Symbol#casecmp?' do upper_a_tilde.casecmp?(lower_a_tilde).should == nil lower_a_tilde.casecmp?(upper_a_tilde).should == nil end + + it "returns true for empty symbols in different encodings" do + ''.to_sym.should.casecmp?(''.encode("UTF-32LE").to_sym) + end end diff --git a/spec/ruby/core/thread/kill_spec.rb b/spec/ruby/core/thread/kill_spec.rb index f932bf5232..4b62c686c7 100644 --- a/spec/ruby/core/thread/kill_spec.rb +++ b/spec/ruby/core/thread/kill_spec.rb @@ -9,10 +9,6 @@ platform_is_not :mingw do it_behaves_like :thread_exit, :kill end - describe "Thread#kill!" do - it "needs to be reviewed for spec completeness" - end - describe "Thread.kill" do it "causes the given thread to exit" do thread = Thread.new { sleep } diff --git a/spec/ruby/core/thread/native_thread_id_spec.rb b/spec/ruby/core/thread/native_thread_id_spec.rb index d6cc332bf6..8460a1db8c 100644 --- a/spec/ruby/core/thread/native_thread_id_spec.rb +++ b/spec/ruby/core/thread/native_thread_id_spec.rb @@ -1,17 +1,30 @@ require_relative '../../spec_helper' -if ruby_version_is "3.1" and Thread.method_defined?(:native_thread_id) - # This method is very platform specific +ruby_version_is "3.1" do + platform_is :linux, :darwin, :windows, :freebsd do + describe "Thread#native_thread_id" do + it "returns an integer when the thread is alive" do + Thread.current.native_thread_id.should be_kind_of(Integer) + end - describe "Thread#native_thread_id" do - it "returns an integer when the thread is alive" do - Thread.current.native_thread_id.should be_kind_of(Integer) - end + it "returns nil when the thread is not running" do + t = Thread.new {} + t.join + t.native_thread_id.should == nil + end + + it "each thread has different native thread id" do + t = Thread.new { sleep } + Thread.pass until t.stop? + main_thread_id = Thread.current.native_thread_id + t_thread_id = t.native_thread_id - it "returns nil when the thread is not running" do - t = Thread.new {} - t.join - t.native_thread_id.should == nil + t_thread_id.should be_kind_of(Integer) + main_thread_id.should_not == t_thread_id + t.run + t.join + t.native_thread_id.should == nil + end end end end diff --git a/spec/ruby/core/thread/shared/exit.rb b/spec/ruby/core/thread/shared/exit.rb index 3663827579..13e8832684 100644 --- a/spec/ruby/core/thread/shared/exit.rb +++ b/spec/ruby/core/thread/shared/exit.rb @@ -113,6 +113,25 @@ describe :thread_exit, shared: true do ScratchPad.recorded.should == nil end + it "kills other fibers of that thread without running their ensure clauses" do + t = Thread.new do + f = Fiber.new do + ScratchPad.record :fiber_resumed + begin + Fiber.yield + ensure + ScratchPad.record :fiber_ensure + end + end + f.resume + sleep + end + Thread.pass until t.stop? + t.send(@method) + t.join + ScratchPad.recorded.should == :fiber_resumed + end + # This spec is a mess. It fails randomly, it hangs on MRI, it needs to be removed quarantine! do it "killing dying running does nothing" do diff --git a/spec/ruby/core/time/succ_spec.rb b/spec/ruby/core/time/succ_spec.rb index e8249059d1..cbf7cf0951 100644 --- a/spec/ruby/core/time/succ_spec.rb +++ b/spec/ruby/core/time/succ_spec.rb @@ -1,5 +1,6 @@ +require_relative '../../spec_helper' + ruby_version_is ""..."3.0" do - require_relative '../../spec_helper' require_relative 'fixtures/classes' describe "Time#succ" do diff --git a/spec/ruby/core/unboundmethod/bind_call_spec.rb b/spec/ruby/core/unboundmethod/bind_call_spec.rb index 8f25f8bd0d..80b2095d86 100644 --- a/spec/ruby/core/unboundmethod/bind_call_spec.rb +++ b/spec/ruby/core/unboundmethod/bind_call_spec.rb @@ -7,6 +7,8 @@ describe "UnboundMethod#bind_call" do @parent_um = UnboundMethodSpecs::Parent.new.method(:foo).unbind @child1_um = UnboundMethodSpecs::Child1.new.method(:foo).unbind @child2_um = UnboundMethodSpecs::Child2.new.method(:foo).unbind + @normal_um_super = UnboundMethodSpecs::Mod.instance_method(:foo_super) + @parent_um_super = UnboundMethodSpecs::Parent.new.method(:foo_super).unbind end it "raises TypeError if object is not kind_of? the Module the method defined in" do @@ -47,4 +49,10 @@ describe "UnboundMethod#bind_call" do um = p.method(:singleton_method).unbind ->{ um.bind_call(other) }.should raise_error(TypeError) end + + it "allows calling super for module methods bound to hierarchies that do not already have that module" do + p = UnboundMethodSpecs::Parent.new + + @normal_um_super.bind_call(p).should == true + end end diff --git a/spec/ruby/core/unboundmethod/bind_spec.rb b/spec/ruby/core/unboundmethod/bind_spec.rb index 03aaa22e74..7658b664e5 100644 --- a/spec/ruby/core/unboundmethod/bind_spec.rb +++ b/spec/ruby/core/unboundmethod/bind_spec.rb @@ -7,6 +7,8 @@ describe "UnboundMethod#bind" do @parent_um = UnboundMethodSpecs::Parent.new.method(:foo).unbind @child1_um = UnboundMethodSpecs::Child1.new.method(:foo).unbind @child2_um = UnboundMethodSpecs::Child2.new.method(:foo).unbind + @normal_um_super = UnboundMethodSpecs::Mod.instance_method(:foo_super) + @parent_um_super = UnboundMethodSpecs::Parent.new.method(:foo_super).unbind end it "raises TypeError if object is not kind_of? the Module the method defined in" do @@ -58,4 +60,10 @@ describe "UnboundMethod#bind" do um = p.method(:singleton_method).unbind ->{ um.bind(other) }.should raise_error(TypeError) end + + it "allows calling super for module methods bound to hierarchies that do not already have that module" do + p = UnboundMethodSpecs::Parent.new + + @normal_um_super.bind(p).call.should == true + end end diff --git a/spec/ruby/core/unboundmethod/fixtures/classes.rb b/spec/ruby/core/unboundmethod/fixtures/classes.rb index 6ab958d447..28d8e0a965 100644 --- a/spec/ruby/core/unboundmethod/fixtures/classes.rb +++ b/spec/ruby/core/unboundmethod/fixtures/classes.rb @@ -22,6 +22,7 @@ module UnboundMethodSpecs module Mod def from_mod; end + def foo_super; super; end end class Methods @@ -63,6 +64,9 @@ module UnboundMethodSpecs class Parent def foo; end + def foo_super + true + end def self.class_method "I am #{name}" end diff --git a/spec/ruby/fixtures/constants.rb b/spec/ruby/fixtures/constants.rb index 47a8e87e56..ffe45fb1f6 100644 --- a/spec/ruby/fixtures/constants.rb +++ b/spec/ruby/fixtures/constants.rb @@ -44,6 +44,7 @@ module ConstantSpecs # Included in ParentA module ModuleB + LINE = __LINE__ - 1 CS_CONST10 = :const10_9 CS_CONST11 = :const11_2 CS_CONST12 = :const12_1 @@ -87,7 +88,7 @@ module ConstantSpecs # are run. class ClassA - CS_CLASS_A_LINE = __LINE__ - 1 + LINE = __LINE__ - 1 CS_CONST10 = :const10_10 CS_CONST10_LINE = __LINE__ - 1 CS_CONST16 = :const16 diff --git a/spec/ruby/language/END_spec.rb b/spec/ruby/language/END_spec.rb index 787f602d88..c84f0cc9ac 100644 --- a/spec/ruby/language/END_spec.rb +++ b/spec/ruby/language/END_spec.rb @@ -1,19 +1,33 @@ require_relative '../spec_helper' +require_relative '../shared/kernel/at_exit' describe "The END keyword" do + it_behaves_like :kernel_at_exit, :END + it "runs only once for multiple calls" do ruby_exe("10.times { END { puts 'foo' }; } ").should == "foo\n" end - it "runs last in a given code unit" do - ruby_exe("END { puts 'bar' }; puts'foo'; ").should == "foo\nbar\n" + it "is affected by the toplevel assignment" do + ruby_exe("foo = 'foo'; END { puts foo }").should == "foo\n" end - it "runs multiple ends in LIFO order" do - ruby_exe("END { puts 'foo' }; END { puts 'bar' }").should == "bar\nfoo\n" + it "warns when END is used in a method" do + ruby_exe(<<~ruby, args: "2>&1").should =~ /warning: END in method; use at_exit/ + def foo + END { } + end + ruby end - it "is affected by the toplevel assignment" do - ruby_exe("foo = 'foo'; END { puts foo }").should == "foo\n" + context "END blocks and at_exit callbacks are mixed" do + it "runs them all in reverse order of registration" do + ruby_exe(<<~ruby).should == "at_exit#2\nEND#2\nat_exit#1\nEND#1\n" + END { puts 'END#1' } + at_exit { puts 'at_exit#1' } + END { puts 'END#2' } + at_exit { puts 'at_exit#2' } + ruby + end end end diff --git a/spec/ruby/language/fixtures/super.rb b/spec/ruby/language/fixtures/super.rb index 218f1e4970..94a2a91be0 100644 --- a/spec/ruby/language/fixtures/super.rb +++ b/spec/ruby/language/fixtures/super.rb @@ -556,6 +556,20 @@ module SuperSpecs end end + module ZSuperInBlock + class A + def m(arg:) + arg + end + end + + class B < A + def m(arg:) + proc { super }.call + end + end + end + module Keywords class Arguments def foo(**args) diff --git a/spec/ruby/language/hash_spec.rb b/spec/ruby/language/hash_spec.rb index c84564d3ea..fa5c8723e9 100644 --- a/spec/ruby/language/hash_spec.rb +++ b/spec/ruby/language/hash_spec.rb @@ -127,11 +127,24 @@ describe "Hash literal" do {a: 1, **h, c: 4}.should == {a: 1, b: 2, c: 4} end - it "expands an '**{}' element with the last key/value pair taking precedence" do + it "expands an '**{}' or '**obj' element with the last key/value pair taking precedence" do -> { @h = eval "{a: 1, **{a: 2, b: 3, c: 1}, c: 3}" }.should complain(/key :a is duplicated|duplicated key/) @h.should == {a: 2, b: 3, c: 3} + + -> { + h = {a: 2, b: 3, c: 1} + @h = eval "{a: 1, **h, c: 3}" + }.should_not complain + @h.should == {a: 2, b: 3, c: 3} + end + + it "expands an '**{}' and warns when finding an additional duplicate key afterwards" do + -> { + @h = eval "{d: 1, **{a: 2, b: 3, c: 1}, c: 3}" + }.should complain(/key :c is duplicated|duplicated key/) + @h.should == {a: 2, b: 3, c: 3, d: 1} end it "merges multiple nested '**obj' in Hash literals" do @@ -177,6 +190,22 @@ describe "Hash literal" do utf8_hash.keys.first.should == usascii_hash.keys.first usascii_hash.keys.first.encoding.should == Encoding::US_ASCII end + + it "raises an EncodingError at parse time when Symbol key with invalid bytes" do + ScratchPad.record [] + -> { + eval 'ScratchPad << 1; {:"\xC3" => 1}' + }.should raise_error(EncodingError, 'invalid symbol in encoding UTF-8 :"\xC3"') + ScratchPad.recorded.should == [] + end + + it "raises an EncodingError at parse time when Symbol key with invalid bytes and 'key: value' syntax used" do + ScratchPad.record [] + -> { + eval 'ScratchPad << 1; {"\xC3": 1}' + }.should raise_error(EncodingError, 'invalid symbol in encoding UTF-8 :"\xC3"') + ScratchPad.recorded.should == [] + end end describe "The ** operator" do diff --git a/spec/ruby/language/if_spec.rb b/spec/ruby/language/if_spec.rb index d1d95c1607..a5da696000 100644 --- a/spec/ruby/language/if_spec.rb +++ b/spec/ruby/language/if_spec.rb @@ -306,6 +306,49 @@ describe "The if expression" do ScratchPad.recorded.should == [4, 5, 4, 5] end end + + describe "when a branch syntactically does not return a value" do + it "raises SyntaxError if both do not return a value" do + -> { + eval <<~RUBY + def m + a = if rand + return + else + return + end + a + end + RUBY + }.should raise_error(SyntaxError, /void value expression/) + end + + it "does not raise SyntaxError if one branch returns a value" do + eval(<<~RUBY).should == 1 + def m + a = if false # using false to make it clear that's not checked for + 42 + else + return 1 + end + a + end + m + RUBY + + eval(<<~RUBY).should == 1 + def m + a = if true # using true to make it clear that's not checked for + return 1 + else + 42 + end + a + end + m + RUBY + end + end end describe "The postfix if form" do diff --git a/spec/ruby/language/regexp/character_classes_spec.rb b/spec/ruby/language/regexp/character_classes_spec.rb index 12a51178b2..a86200ff34 100644 --- a/spec/ruby/language/regexp/character_classes_spec.rb +++ b/spec/ruby/language/regexp/character_classes_spec.rb @@ -610,8 +610,8 @@ describe "Regexp with character classes" do end it "supports negated property condition" do - "a".match(/\P{L}/).should be_nil - "1".match(/\P{N}/).should be_nil + "a".match(eval("/\P{L}/")).should be_nil + "1".match(eval("/\P{N}/")).should be_nil end ruby_bug "#17340", ''...'3.0' do diff --git a/spec/ruby/language/super_spec.rb b/spec/ruby/language/super_spec.rb index 1ac5c5e1be..1fd7acc727 100644 --- a/spec/ruby/language/super_spec.rb +++ b/spec/ruby/language/super_spec.rb @@ -322,6 +322,10 @@ describe "The super keyword" do SuperSpecs::ZSuperWithUnderscores::B.new.m_modified(1, 2).should == [14, 2] end + it "should pass method arguments when called within a closure" do + SuperSpecs::ZSuperInBlock::B.new.m(arg: 1).should == 1 + end + describe 'when using keyword arguments' do before :each do @req = SuperSpecs::Keywords::RequiredArguments.new diff --git a/spec/ruby/language/symbol_spec.rb b/spec/ruby/language/symbol_spec.rb index d6a41d3059..7c1898efc2 100644 --- a/spec/ruby/language/symbol_spec.rb +++ b/spec/ruby/language/symbol_spec.rb @@ -96,11 +96,11 @@ describe "A Symbol literal" do %I{a b #{"c"}}.should == [:a, :b, :c] end - it "with invalid bytes raises an EncodingError at parse time" do + it "raises an EncodingError at parse time when Symbol with invalid bytes" do ScratchPad.record [] -> { eval 'ScratchPad << 1; :"\xC3"' - }.should raise_error(EncodingError, /invalid/) + }.should raise_error(EncodingError, 'invalid symbol in encoding UTF-8 :"\xC3"') ScratchPad.recorded.should == [] end end diff --git a/spec/ruby/library/date/strftime_spec.rb b/spec/ruby/library/date/strftime_spec.rb index 8b1ebe061c..33ecc4ce9d 100644 --- a/spec/ruby/library/date/strftime_spec.rb +++ b/spec/ruby/library/date/strftime_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../spec_helper" require 'date' require_relative '../../shared/time/strftime_for_date' diff --git a/spec/ruby/library/delegate/delegate_class/respond_to_missing_spec.rb b/spec/ruby/library/delegate/delegate_class/respond_to_missing_spec.rb index 729cfc96c6..3975e5208b 100644 --- a/spec/ruby/library/delegate/delegate_class/respond_to_missing_spec.rb +++ b/spec/ruby/library/delegate/delegate_class/respond_to_missing_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" require 'delegate' describe "DelegateClass#respond_to_missing?" do diff --git a/spec/ruby/library/etc/confstr_spec.rb b/spec/ruby/library/etc/confstr_spec.rb index 41a970a918..5b43461150 100644 --- a/spec/ruby/library/etc/confstr_spec.rb +++ b/spec/ruby/library/etc/confstr_spec.rb @@ -1,4 +1,4 @@ -require File.expand_path('../../../spec_helper', __FILE__) +require_relative '../../spec_helper' require 'etc' platform_is_not :windows, :android do diff --git a/spec/ruby/library/etc/passwd_spec.rb b/spec/ruby/library/etc/passwd_spec.rb index d61dada451..7157fd3f2e 100644 --- a/spec/ruby/library/etc/passwd_spec.rb +++ b/spec/ruby/library/etc/passwd_spec.rb @@ -1,4 +1,4 @@ -require File.expand_path('../../../spec_helper', __FILE__) +require_relative '../../spec_helper' require 'etc' platform_is_not :windows do diff --git a/spec/ruby/library/etc/sysconf_spec.rb b/spec/ruby/library/etc/sysconf_spec.rb index e7d59d1b22..1f2c7a770f 100644 --- a/spec/ruby/library/etc/sysconf_spec.rb +++ b/spec/ruby/library/etc/sysconf_spec.rb @@ -1,4 +1,4 @@ -require File.expand_path('../../../spec_helper', __FILE__) +require_relative '../../spec_helper' require 'etc' platform_is_not :windows do diff --git a/spec/ruby/library/etc/sysconfdir_spec.rb b/spec/ruby/library/etc/sysconfdir_spec.rb index d54299c513..8538faa65b 100644 --- a/spec/ruby/library/etc/sysconfdir_spec.rb +++ b/spec/ruby/library/etc/sysconfdir_spec.rb @@ -1,4 +1,4 @@ -require File.expand_path('../../../spec_helper', __FILE__) +require_relative '../../spec_helper' require 'etc' describe "Etc.sysconfdir" do diff --git a/spec/ruby/library/etc/systmpdir_spec.rb b/spec/ruby/library/etc/systmpdir_spec.rb index 99c82903f8..5b007aa9f9 100644 --- a/spec/ruby/library/etc/systmpdir_spec.rb +++ b/spec/ruby/library/etc/systmpdir_spec.rb @@ -1,4 +1,4 @@ -require File.expand_path('../../../spec_helper', __FILE__) +require_relative '../../spec_helper' require 'etc' describe "Etc.systmpdir" do diff --git a/spec/ruby/library/expect/expect_spec.rb b/spec/ruby/library/expect/expect_spec.rb index a7041d42ee..76ea3d5451 100644 --- a/spec/ruby/library/expect/expect_spec.rb +++ b/spec/ruby/library/expect/expect_spec.rb @@ -1,5 +1,6 @@ +require_relative '../../spec_helper' + platform_is_not :windows do - require_relative '../../spec_helper' require 'expect' describe "IO#expect" do diff --git a/spec/ruby/library/rubygems/gem/load_path_insert_index_spec.rb b/spec/ruby/library/rubygems/gem/load_path_insert_index_spec.rb index 58913cddab..9b37eaa43c 100644 --- a/spec/ruby/library/rubygems/gem/load_path_insert_index_spec.rb +++ b/spec/ruby/library/rubygems/gem/load_path_insert_index_spec.rb @@ -3,7 +3,7 @@ require 'rubygems' describe "Gem.load_path_insert_index" do guard -> { RbConfig::TOPDIR } do - it "is set for an installed an installed Ruby" do + it "is set for an installed Ruby" do Gem.load_path_insert_index.should be_kind_of Integer end end diff --git a/spec/ruby/library/set/comparison_spec.rb b/spec/ruby/library/set/comparison_spec.rb index b851ea3d57..6b7a71e659 100644 --- a/spec/ruby/library/set/comparison_spec.rb +++ b/spec/ruby/library/set/comparison_spec.rb @@ -1,29 +1,29 @@ -require_relative '../../spec_helper' -require 'set' - -ruby_version_is "3.0" do - describe "Set#<=>" do - it "returns 0 if the sets are equal" do - (Set[] <=> Set[]).should == 0 - (Set[:a, :b, :c] <=> Set[:a, :b, :c]).should == 0 - end - - it "returns -1 if the set is a proper subset of the other set" do - (Set[] <=> Set[1]).should == -1 - (Set[1, 2] <=> Set[1, 2, 3]).should == -1 - end - - it "returns +1 if the set is a proper superset of other set" do - (Set[1] <=> Set[]).should == +1 - (Set[1, 2, 3] <=> Set[1, 2]).should == +1 - end - - it "returns nil if the set has unique elements" do - (Set[1, 2, 3] <=> Set[:a, :b, :c]).should be_nil - end - - it "returns nil when the argument is not set-like" do - (Set[] <=> false).should be_nil - end - end -end +require_relative '../../spec_helper' +require 'set' + +ruby_version_is "3.0" do + describe "Set#<=>" do + it "returns 0 if the sets are equal" do + (Set[] <=> Set[]).should == 0 + (Set[:a, :b, :c] <=> Set[:a, :b, :c]).should == 0 + end + + it "returns -1 if the set is a proper subset of the other set" do + (Set[] <=> Set[1]).should == -1 + (Set[1, 2] <=> Set[1, 2, 3]).should == -1 + end + + it "returns +1 if the set is a proper superset of other set" do + (Set[1] <=> Set[]).should == +1 + (Set[1, 2, 3] <=> Set[1, 2]).should == +1 + end + + it "returns nil if the set has unique elements" do + (Set[1, 2, 3] <=> Set[:a, :b, :c]).should be_nil + end + + it "returns nil when the argument is not set-like" do + (Set[] <=> false).should be_nil + end + end +end diff --git a/spec/ruby/library/set/each_spec.rb b/spec/ruby/library/set/each_spec.rb index 9bb5ead03a..44e185a4da 100644 --- a/spec/ruby/library/set/each_spec.rb +++ b/spec/ruby/library/set/each_spec.rb @@ -18,6 +18,7 @@ describe "Set#each" do it "returns an Enumerator when not passed a block" do enum = @set.each + enum.should be_an_instance_of(Enumerator) ret = [] enum.each { |x| ret << x } diff --git a/spec/ruby/library/set/to_s_spec.rb b/spec/ruby/library/set/to_s_spec.rb index 7b9f7b6603..3c26ae9346 100644 --- a/spec/ruby/library/set/to_s_spec.rb +++ b/spec/ruby/library/set/to_s_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../spec_helper" require_relative 'shared/inspect' require 'set' diff --git a/spec/ruby/library/socket/tcpsocket/open_spec.rb b/spec/ruby/library/socket/tcpsocket/open_spec.rb index 31b630a23b..0c0b579064 100644 --- a/spec/ruby/library/socket/tcpsocket/open_spec.rb +++ b/spec/ruby/library/socket/tcpsocket/open_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" require_relative 'shared/new' describe "TCPSocket.open" do diff --git a/spec/ruby/library/win32ole/win32ole/_getproperty_spec.rb b/spec/ruby/library/win32ole/win32ole/_getproperty_spec.rb index 940eebfb91..52cb978bea 100644 --- a/spec/ruby/library/win32ole/win32ole/_getproperty_spec.rb +++ b/spec/ruby/library/win32ole/win32ole/_getproperty_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require_relative '../fixtures/classes' diff --git a/spec/ruby/library/win32ole/win32ole/_invoke_spec.rb b/spec/ruby/library/win32ole/win32ole/_invoke_spec.rb index 91f5091d24..994c2e6d36 100644 --- a/spec/ruby/library/win32ole/win32ole/_invoke_spec.rb +++ b/spec/ruby/library/win32ole/win32ole/_invoke_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require_relative '../fixtures/classes' diff --git a/spec/ruby/library/win32ole/win32ole/codepage_spec.rb b/spec/ruby/library/win32ole/win32ole/codepage_spec.rb index 4e0cf5ca55..07e93646ac 100644 --- a/spec/ruby/library/win32ole/win32ole/codepage_spec.rb +++ b/spec/ruby/library/win32ole/win32ole/codepage_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require_relative '../fixtures/classes' diff --git a/spec/ruby/library/win32ole/win32ole/connect_spec.rb b/spec/ruby/library/win32ole/win32ole/connect_spec.rb index 72dceb1572..ac0976ddc1 100644 --- a/spec/ruby/library/win32ole/win32ole/connect_spec.rb +++ b/spec/ruby/library/win32ole/win32ole/connect_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require_relative '../fixtures/classes' diff --git a/spec/ruby/library/win32ole/win32ole/const_load_spec.rb b/spec/ruby/library/win32ole/win32ole/const_load_spec.rb index cacc7a2b22..2099c4aa66 100644 --- a/spec/ruby/library/win32ole/win32ole/const_load_spec.rb +++ b/spec/ruby/library/win32ole/win32ole/const_load_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require_relative '../fixtures/classes' diff --git a/spec/ruby/library/win32ole/win32ole/constants_spec.rb b/spec/ruby/library/win32ole/win32ole/constants_spec.rb index 978b7ade92..8533741440 100644 --- a/spec/ruby/library/win32ole/win32ole/constants_spec.rb +++ b/spec/ruby/library/win32ole/win32ole/constants_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require_relative '../fixtures/classes' diff --git a/spec/ruby/library/win32ole/win32ole/create_guid_spec.rb b/spec/ruby/library/win32ole/win32ole/create_guid_spec.rb index 2e18b6ab11..8aa853df9e 100644 --- a/spec/ruby/library/win32ole/win32ole/create_guid_spec.rb +++ b/spec/ruby/library/win32ole/win32ole/create_guid_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require_relative '../fixtures/classes' diff --git a/spec/ruby/library/win32ole/win32ole/invoke_spec.rb b/spec/ruby/library/win32ole/win32ole/invoke_spec.rb index 08a5156e05..d6ff7fade3 100644 --- a/spec/ruby/library/win32ole/win32ole/invoke_spec.rb +++ b/spec/ruby/library/win32ole/win32ole/invoke_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require_relative '../fixtures/classes' diff --git a/spec/ruby/library/win32ole/win32ole/locale_spec.rb b/spec/ruby/library/win32ole/win32ole/locale_spec.rb index 75a82ddd7f..78ede4375a 100644 --- a/spec/ruby/library/win32ole/win32ole/locale_spec.rb +++ b/spec/ruby/library/win32ole/win32ole/locale_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require_relative '../fixtures/classes' diff --git a/spec/ruby/library/win32ole/win32ole/new_spec.rb b/spec/ruby/library/win32ole/win32ole/new_spec.rb index 6b717195f1..7e91c2d3ea 100644 --- a/spec/ruby/library/win32ole/win32ole/new_spec.rb +++ b/spec/ruby/library/win32ole/win32ole/new_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require_relative '../fixtures/classes' diff --git a/spec/ruby/library/win32ole/win32ole/ole_func_methods_spec.rb b/spec/ruby/library/win32ole/win32ole/ole_func_methods_spec.rb index 75748182fe..2bbe8c27d4 100644 --- a/spec/ruby/library/win32ole/win32ole/ole_func_methods_spec.rb +++ b/spec/ruby/library/win32ole/win32ole/ole_func_methods_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require_relative '../fixtures/classes' diff --git a/spec/ruby/library/win32ole/win32ole/ole_get_methods_spec.rb b/spec/ruby/library/win32ole/win32ole/ole_get_methods_spec.rb index a991624a23..c1d1970214 100644 --- a/spec/ruby/library/win32ole/win32ole/ole_get_methods_spec.rb +++ b/spec/ruby/library/win32ole/win32ole/ole_get_methods_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require_relative '../fixtures/classes' diff --git a/spec/ruby/library/win32ole/win32ole/ole_method_help_spec.rb b/spec/ruby/library/win32ole/win32ole/ole_method_help_spec.rb index 8a26d79a20..9cb3f9e6cf 100644 --- a/spec/ruby/library/win32ole/win32ole/ole_method_help_spec.rb +++ b/spec/ruby/library/win32ole/win32ole/ole_method_help_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require_relative '../fixtures/classes' require_relative 'shared/ole_method' diff --git a/spec/ruby/library/win32ole/win32ole/ole_method_spec.rb b/spec/ruby/library/win32ole/win32ole/ole_method_spec.rb index f82a212f5d..e48ff8d905 100644 --- a/spec/ruby/library/win32ole/win32ole/ole_method_spec.rb +++ b/spec/ruby/library/win32ole/win32ole/ole_method_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require_relative '../fixtures/classes' require_relative 'shared/ole_method' diff --git a/spec/ruby/library/win32ole/win32ole/ole_methods_spec.rb b/spec/ruby/library/win32ole/win32ole/ole_methods_spec.rb index 5ac9ae9cfa..fe161ce9f0 100644 --- a/spec/ruby/library/win32ole/win32ole/ole_methods_spec.rb +++ b/spec/ruby/library/win32ole/win32ole/ole_methods_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require_relative '../fixtures/classes' diff --git a/spec/ruby/library/win32ole/win32ole/ole_obj_help_spec.rb b/spec/ruby/library/win32ole/win32ole/ole_obj_help_spec.rb index ef8944ee39..afcf16a051 100644 --- a/spec/ruby/library/win32ole/win32ole/ole_obj_help_spec.rb +++ b/spec/ruby/library/win32ole/win32ole/ole_obj_help_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require_relative '../fixtures/classes' diff --git a/spec/ruby/library/win32ole/win32ole/ole_put_methods_spec.rb b/spec/ruby/library/win32ole/win32ole/ole_put_methods_spec.rb index 727291e9f0..c091c83c95 100644 --- a/spec/ruby/library/win32ole/win32ole/ole_put_methods_spec.rb +++ b/spec/ruby/library/win32ole/win32ole/ole_put_methods_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require_relative '../fixtures/classes' diff --git a/spec/ruby/library/win32ole/win32ole/setproperty_spec.rb b/spec/ruby/library/win32ole/win32ole/setproperty_spec.rb index 7409823f20..bacdee63da 100644 --- a/spec/ruby/library/win32ole/win32ole/setproperty_spec.rb +++ b/spec/ruby/library/win32ole/win32ole/setproperty_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require_relative '../fixtures/classes' require_relative 'shared/setproperty' diff --git a/spec/ruby/library/win32ole/win32ole_event/new_spec.rb b/spec/ruby/library/win32ole/win32ole_event/new_spec.rb index a1a1612393..94fabb1e3b 100644 --- a/spec/ruby/library/win32ole/win32ole_event/new_spec.rb +++ b/spec/ruby/library/win32ole/win32ole_event/new_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require_relative '../fixtures/classes' diff --git a/spec/ruby/library/win32ole/win32ole_event/on_event_spec.rb b/spec/ruby/library/win32ole/win32ole_event/on_event_spec.rb index feb26b0637..0957bdd2d4 100644 --- a/spec/ruby/library/win32ole/win32ole_event/on_event_spec.rb +++ b/spec/ruby/library/win32ole/win32ole_event/on_event_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require_relative '../fixtures/classes' guard -> { WIN32OLESpecs::MSXML_AVAILABLE } do diff --git a/spec/ruby/library/win32ole/win32ole_method/dispid_spec.rb b/spec/ruby/library/win32ole/win32ole_method/dispid_spec.rb index 69068683b7..ece71df0d4 100644 --- a/spec/ruby/library/win32ole/win32ole_method/dispid_spec.rb +++ b/spec/ruby/library/win32ole/win32ole_method/dispid_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require 'win32ole' diff --git a/spec/ruby/library/win32ole/win32ole_method/event_interface_spec.rb b/spec/ruby/library/win32ole/win32ole_method/event_interface_spec.rb index 70c8b30cca..78634d2fde 100644 --- a/spec/ruby/library/win32ole/win32ole_method/event_interface_spec.rb +++ b/spec/ruby/library/win32ole/win32ole_method/event_interface_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require_relative '../fixtures/classes' guard -> { WIN32OLESpecs::SYSTEM_MONITOR_CONTROL_AVAILABLE } do diff --git a/spec/ruby/library/win32ole/win32ole_method/event_spec.rb b/spec/ruby/library/win32ole/win32ole_method/event_spec.rb index c41f8fe99d..9b642a010c 100644 --- a/spec/ruby/library/win32ole/win32ole_method/event_spec.rb +++ b/spec/ruby/library/win32ole/win32ole_method/event_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require_relative '../fixtures/classes' guard -> { WIN32OLESpecs::SYSTEM_MONITOR_CONTROL_AVAILABLE } do diff --git a/spec/ruby/library/win32ole/win32ole_method/helpcontext_spec.rb b/spec/ruby/library/win32ole/win32ole_method/helpcontext_spec.rb index 21b3ae8bde..d1c5ee3be2 100644 --- a/spec/ruby/library/win32ole/win32ole_method/helpcontext_spec.rb +++ b/spec/ruby/library/win32ole/win32ole_method/helpcontext_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require 'win32ole' diff --git a/spec/ruby/library/win32ole/win32ole_method/helpfile_spec.rb b/spec/ruby/library/win32ole/win32ole_method/helpfile_spec.rb index b6d0a19a37..59dad9244c 100644 --- a/spec/ruby/library/win32ole/win32ole_method/helpfile_spec.rb +++ b/spec/ruby/library/win32ole/win32ole_method/helpfile_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require 'win32ole' diff --git a/spec/ruby/library/win32ole/win32ole_method/helpstring_spec.rb b/spec/ruby/library/win32ole/win32ole_method/helpstring_spec.rb index 9f940fd4a0..b2f24ba151 100644 --- a/spec/ruby/library/win32ole/win32ole_method/helpstring_spec.rb +++ b/spec/ruby/library/win32ole/win32ole_method/helpstring_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require 'win32ole' diff --git a/spec/ruby/library/win32ole/win32ole_method/invkind_spec.rb b/spec/ruby/library/win32ole/win32ole_method/invkind_spec.rb index 7fff479daf..d7fedf0d36 100644 --- a/spec/ruby/library/win32ole/win32ole_method/invkind_spec.rb +++ b/spec/ruby/library/win32ole/win32ole_method/invkind_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require 'win32ole' diff --git a/spec/ruby/library/win32ole/win32ole_method/invoke_kind_spec.rb b/spec/ruby/library/win32ole/win32ole_method/invoke_kind_spec.rb index e8638abd91..d5536fd17b 100644 --- a/spec/ruby/library/win32ole/win32ole_method/invoke_kind_spec.rb +++ b/spec/ruby/library/win32ole/win32ole_method/invoke_kind_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require 'win32ole' diff --git a/spec/ruby/library/win32ole/win32ole_method/name_spec.rb b/spec/ruby/library/win32ole/win32ole_method/name_spec.rb index cd5404fc54..477b820f4d 100644 --- a/spec/ruby/library/win32ole/win32ole_method/name_spec.rb +++ b/spec/ruby/library/win32ole/win32ole_method/name_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" require_relative 'shared/name' platform_is :windows do diff --git a/spec/ruby/library/win32ole/win32ole_method/new_spec.rb b/spec/ruby/library/win32ole/win32ole_method/new_spec.rb index 8ebf93b992..4e427421b9 100644 --- a/spec/ruby/library/win32ole/win32ole_method/new_spec.rb +++ b/spec/ruby/library/win32ole/win32ole_method/new_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require 'win32ole' diff --git a/spec/ruby/library/win32ole/win32ole_method/offset_vtbl_spec.rb b/spec/ruby/library/win32ole/win32ole_method/offset_vtbl_spec.rb index 8e50c39787..b3da9a8303 100644 --- a/spec/ruby/library/win32ole/win32ole_method/offset_vtbl_spec.rb +++ b/spec/ruby/library/win32ole/win32ole_method/offset_vtbl_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require 'win32ole' diff --git a/spec/ruby/library/win32ole/win32ole_method/params_spec.rb b/spec/ruby/library/win32ole/win32ole_method/params_spec.rb index 2f8da3d45b..09fb0eb5ac 100644 --- a/spec/ruby/library/win32ole/win32ole_method/params_spec.rb +++ b/spec/ruby/library/win32ole/win32ole_method/params_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require 'win32ole' diff --git a/spec/ruby/library/win32ole/win32ole_method/return_type_detail_spec.rb b/spec/ruby/library/win32ole/win32ole_method/return_type_detail_spec.rb index f8ce3e1b3a..582a5951d5 100644 --- a/spec/ruby/library/win32ole/win32ole_method/return_type_detail_spec.rb +++ b/spec/ruby/library/win32ole/win32ole_method/return_type_detail_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require 'win32ole' diff --git a/spec/ruby/library/win32ole/win32ole_method/return_type_spec.rb b/spec/ruby/library/win32ole/win32ole_method/return_type_spec.rb index 58e26df77b..dd8add402d 100644 --- a/spec/ruby/library/win32ole/win32ole_method/return_type_spec.rb +++ b/spec/ruby/library/win32ole/win32ole_method/return_type_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require 'win32ole' diff --git a/spec/ruby/library/win32ole/win32ole_method/return_vtype_spec.rb b/spec/ruby/library/win32ole/win32ole_method/return_vtype_spec.rb index dc159dd09e..3fca3d54ed 100644 --- a/spec/ruby/library/win32ole/win32ole_method/return_vtype_spec.rb +++ b/spec/ruby/library/win32ole/win32ole_method/return_vtype_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require 'win32ole' diff --git a/spec/ruby/library/win32ole/win32ole_method/size_opt_params_spec.rb b/spec/ruby/library/win32ole/win32ole_method/size_opt_params_spec.rb index a38fe5c681..fe9facb53a 100644 --- a/spec/ruby/library/win32ole/win32ole_method/size_opt_params_spec.rb +++ b/spec/ruby/library/win32ole/win32ole_method/size_opt_params_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require 'win32ole' diff --git a/spec/ruby/library/win32ole/win32ole_method/size_params_spec.rb b/spec/ruby/library/win32ole/win32ole_method/size_params_spec.rb index 0c5a94c338..8ea6e61e7d 100644 --- a/spec/ruby/library/win32ole/win32ole_method/size_params_spec.rb +++ b/spec/ruby/library/win32ole/win32ole_method/size_params_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require 'win32ole' diff --git a/spec/ruby/library/win32ole/win32ole_method/to_s_spec.rb b/spec/ruby/library/win32ole/win32ole_method/to_s_spec.rb index ecb3c08038..11107a77fc 100644 --- a/spec/ruby/library/win32ole/win32ole_method/to_s_spec.rb +++ b/spec/ruby/library/win32ole/win32ole_method/to_s_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" require_relative 'shared/name' platform_is :windows do diff --git a/spec/ruby/library/win32ole/win32ole_method/visible_spec.rb b/spec/ruby/library/win32ole/win32ole_method/visible_spec.rb index 918b6ef782..d1a50523fc 100644 --- a/spec/ruby/library/win32ole/win32ole_method/visible_spec.rb +++ b/spec/ruby/library/win32ole/win32ole_method/visible_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require 'win32ole' diff --git a/spec/ruby/library/win32ole/win32ole_param/default_spec.rb b/spec/ruby/library/win32ole/win32ole_param/default_spec.rb index af08c84782..44bd3d7fd3 100644 --- a/spec/ruby/library/win32ole/win32ole_param/default_spec.rb +++ b/spec/ruby/library/win32ole/win32ole_param/default_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require 'win32ole' diff --git a/spec/ruby/library/win32ole/win32ole_param/input_spec.rb b/spec/ruby/library/win32ole/win32ole_param/input_spec.rb index e2a90daa56..e9134b1df8 100644 --- a/spec/ruby/library/win32ole/win32ole_param/input_spec.rb +++ b/spec/ruby/library/win32ole/win32ole_param/input_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require 'win32ole' diff --git a/spec/ruby/library/win32ole/win32ole_param/name_spec.rb b/spec/ruby/library/win32ole/win32ole_param/name_spec.rb index 0c20c24720..67a8955ba4 100644 --- a/spec/ruby/library/win32ole/win32ole_param/name_spec.rb +++ b/spec/ruby/library/win32ole/win32ole_param/name_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" require_relative 'shared/name' platform_is :windows do diff --git a/spec/ruby/library/win32ole/win32ole_param/ole_type_detail_spec.rb b/spec/ruby/library/win32ole/win32ole_param/ole_type_detail_spec.rb index e683d1c16e..f05455e3f1 100644 --- a/spec/ruby/library/win32ole/win32ole_param/ole_type_detail_spec.rb +++ b/spec/ruby/library/win32ole/win32ole_param/ole_type_detail_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require 'win32ole' diff --git a/spec/ruby/library/win32ole/win32ole_param/ole_type_spec.rb b/spec/ruby/library/win32ole/win32ole_param/ole_type_spec.rb index b9a3639c3e..1467130e03 100644 --- a/spec/ruby/library/win32ole/win32ole_param/ole_type_spec.rb +++ b/spec/ruby/library/win32ole/win32ole_param/ole_type_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require 'win32ole' diff --git a/spec/ruby/library/win32ole/win32ole_param/optional_spec.rb b/spec/ruby/library/win32ole/win32ole_param/optional_spec.rb index 3fb9dc1867..b39ee41179 100644 --- a/spec/ruby/library/win32ole/win32ole_param/optional_spec.rb +++ b/spec/ruby/library/win32ole/win32ole_param/optional_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require 'win32ole' diff --git a/spec/ruby/library/win32ole/win32ole_param/retval_spec.rb b/spec/ruby/library/win32ole/win32ole_param/retval_spec.rb index f5546e79e5..dd613dd29a 100644 --- a/spec/ruby/library/win32ole/win32ole_param/retval_spec.rb +++ b/spec/ruby/library/win32ole/win32ole_param/retval_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require 'win32ole' diff --git a/spec/ruby/library/win32ole/win32ole_param/to_s_spec.rb b/spec/ruby/library/win32ole/win32ole_param/to_s_spec.rb index 5b4b4c1c80..e9153a2eb2 100644 --- a/spec/ruby/library/win32ole/win32ole_param/to_s_spec.rb +++ b/spec/ruby/library/win32ole/win32ole_param/to_s_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" require_relative 'shared/name' platform_is :windows do diff --git a/spec/ruby/library/win32ole/win32ole_type/guid_spec.rb b/spec/ruby/library/win32ole/win32ole_type/guid_spec.rb index 25907c8e32..abdf8d34b9 100644 --- a/spec/ruby/library/win32ole/win32ole_type/guid_spec.rb +++ b/spec/ruby/library/win32ole/win32ole_type/guid_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require 'win32ole' diff --git a/spec/ruby/library/win32ole/win32ole_type/helpcontext_spec.rb b/spec/ruby/library/win32ole/win32ole_type/helpcontext_spec.rb index d436835188..eee23abc56 100644 --- a/spec/ruby/library/win32ole/win32ole_type/helpcontext_spec.rb +++ b/spec/ruby/library/win32ole/win32ole_type/helpcontext_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require 'win32ole' diff --git a/spec/ruby/library/win32ole/win32ole_type/helpfile_spec.rb b/spec/ruby/library/win32ole/win32ole_type/helpfile_spec.rb index 01e6945138..3a0a9ead94 100644 --- a/spec/ruby/library/win32ole/win32ole_type/helpfile_spec.rb +++ b/spec/ruby/library/win32ole/win32ole_type/helpfile_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require 'win32ole' diff --git a/spec/ruby/library/win32ole/win32ole_type/helpstring_spec.rb b/spec/ruby/library/win32ole/win32ole_type/helpstring_spec.rb index 3bd2cbe5dd..9ab0004668 100644 --- a/spec/ruby/library/win32ole/win32ole_type/helpstring_spec.rb +++ b/spec/ruby/library/win32ole/win32ole_type/helpstring_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require 'win32ole' diff --git a/spec/ruby/library/win32ole/win32ole_type/major_version_spec.rb b/spec/ruby/library/win32ole/win32ole_type/major_version_spec.rb index 7dae16617d..7d2731f778 100644 --- a/spec/ruby/library/win32ole/win32ole_type/major_version_spec.rb +++ b/spec/ruby/library/win32ole/win32ole_type/major_version_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require 'win32ole' diff --git a/spec/ruby/library/win32ole/win32ole_type/minor_version_spec.rb b/spec/ruby/library/win32ole/win32ole_type/minor_version_spec.rb index ff412dd100..3904e78d42 100644 --- a/spec/ruby/library/win32ole/win32ole_type/minor_version_spec.rb +++ b/spec/ruby/library/win32ole/win32ole_type/minor_version_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require 'win32ole' diff --git a/spec/ruby/library/win32ole/win32ole_type/name_spec.rb b/spec/ruby/library/win32ole/win32ole_type/name_spec.rb index b7a28c553a..d76998d7dc 100644 --- a/spec/ruby/library/win32ole/win32ole_type/name_spec.rb +++ b/spec/ruby/library/win32ole/win32ole_type/name_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" require_relative 'shared/name' platform_is :windows do diff --git a/spec/ruby/library/win32ole/win32ole_type/new_spec.rb b/spec/ruby/library/win32ole/win32ole_type/new_spec.rb index 3c3aa1c390..cc691ffa67 100644 --- a/spec/ruby/library/win32ole/win32ole_type/new_spec.rb +++ b/spec/ruby/library/win32ole/win32ole_type/new_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require 'win32ole' diff --git a/spec/ruby/library/win32ole/win32ole_type/ole_classes_spec.rb b/spec/ruby/library/win32ole/win32ole_type/ole_classes_spec.rb index 0ce0fc98a4..a3a1d4ac58 100644 --- a/spec/ruby/library/win32ole/win32ole_type/ole_classes_spec.rb +++ b/spec/ruby/library/win32ole/win32ole_type/ole_classes_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require 'win32ole' diff --git a/spec/ruby/library/win32ole/win32ole_type/ole_methods_spec.rb b/spec/ruby/library/win32ole/win32ole_type/ole_methods_spec.rb index 9265549d20..3b99b97a61 100644 --- a/spec/ruby/library/win32ole/win32ole_type/ole_methods_spec.rb +++ b/spec/ruby/library/win32ole/win32ole_type/ole_methods_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require 'win32ole' diff --git a/spec/ruby/library/win32ole/win32ole_type/ole_type_spec.rb b/spec/ruby/library/win32ole/win32ole_type/ole_type_spec.rb index 2bc19aa85e..24292b1c4f 100644 --- a/spec/ruby/library/win32ole/win32ole_type/ole_type_spec.rb +++ b/spec/ruby/library/win32ole/win32ole_type/ole_type_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require 'win32ole' diff --git a/spec/ruby/library/win32ole/win32ole_type/progid_spec.rb b/spec/ruby/library/win32ole/win32ole_type/progid_spec.rb index f0d80ba39e..340fdb34e8 100644 --- a/spec/ruby/library/win32ole/win32ole_type/progid_spec.rb +++ b/spec/ruby/library/win32ole/win32ole_type/progid_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require 'win32ole' diff --git a/spec/ruby/library/win32ole/win32ole_type/progids_spec.rb b/spec/ruby/library/win32ole/win32ole_type/progids_spec.rb index 19d8bf56e0..793535b48d 100644 --- a/spec/ruby/library/win32ole/win32ole_type/progids_spec.rb +++ b/spec/ruby/library/win32ole/win32ole_type/progids_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require 'win32ole' diff --git a/spec/ruby/library/win32ole/win32ole_type/src_type_spec.rb b/spec/ruby/library/win32ole/win32ole_type/src_type_spec.rb index 71e304d80a..3f89fe702a 100644 --- a/spec/ruby/library/win32ole/win32ole_type/src_type_spec.rb +++ b/spec/ruby/library/win32ole/win32ole_type/src_type_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require 'win32ole' diff --git a/spec/ruby/library/win32ole/win32ole_type/to_s_spec.rb b/spec/ruby/library/win32ole/win32ole_type/to_s_spec.rb index b713990ed2..9f086a5a35 100644 --- a/spec/ruby/library/win32ole/win32ole_type/to_s_spec.rb +++ b/spec/ruby/library/win32ole/win32ole_type/to_s_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" require_relative 'shared/name' platform_is :windows do diff --git a/spec/ruby/library/win32ole/win32ole_type/typekind_spec.rb b/spec/ruby/library/win32ole/win32ole_type/typekind_spec.rb index 35f3562721..391d505e01 100644 --- a/spec/ruby/library/win32ole/win32ole_type/typekind_spec.rb +++ b/spec/ruby/library/win32ole/win32ole_type/typekind_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require 'win32ole' diff --git a/spec/ruby/library/win32ole/win32ole_type/typelibs_spec.rb b/spec/ruby/library/win32ole/win32ole_type/typelibs_spec.rb index 369e0274f3..a487208caa 100644 --- a/spec/ruby/library/win32ole/win32ole_type/typelibs_spec.rb +++ b/spec/ruby/library/win32ole/win32ole_type/typelibs_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require 'win32ole' diff --git a/spec/ruby/library/win32ole/win32ole_type/variables_spec.rb b/spec/ruby/library/win32ole/win32ole_type/variables_spec.rb index fbf3dd0341..7f61b8af95 100644 --- a/spec/ruby/library/win32ole/win32ole_type/variables_spec.rb +++ b/spec/ruby/library/win32ole/win32ole_type/variables_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require 'win32ole' diff --git a/spec/ruby/library/win32ole/win32ole_type/visible_spec.rb b/spec/ruby/library/win32ole/win32ole_type/visible_spec.rb index 403b2b843b..99e34edcdd 100644 --- a/spec/ruby/library/win32ole/win32ole_type/visible_spec.rb +++ b/spec/ruby/library/win32ole/win32ole_type/visible_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require 'win32ole' diff --git a/spec/ruby/library/win32ole/win32ole_variable/name_spec.rb b/spec/ruby/library/win32ole/win32ole_variable/name_spec.rb index 8bac1a9891..dd9bfa594f 100644 --- a/spec/ruby/library/win32ole/win32ole_variable/name_spec.rb +++ b/spec/ruby/library/win32ole/win32ole_variable/name_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" require_relative 'shared/name' platform_is :windows do diff --git a/spec/ruby/library/win32ole/win32ole_variable/ole_type_detail_spec.rb b/spec/ruby/library/win32ole/win32ole_variable/ole_type_detail_spec.rb index dab4edabaa..7a9c791494 100644 --- a/spec/ruby/library/win32ole/win32ole_variable/ole_type_detail_spec.rb +++ b/spec/ruby/library/win32ole/win32ole_variable/ole_type_detail_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require 'win32ole' diff --git a/spec/ruby/library/win32ole/win32ole_variable/ole_type_spec.rb b/spec/ruby/library/win32ole/win32ole_variable/ole_type_spec.rb index d08acc9bde..03a9aa4c74 100644 --- a/spec/ruby/library/win32ole/win32ole_variable/ole_type_spec.rb +++ b/spec/ruby/library/win32ole/win32ole_variable/ole_type_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require 'win32ole' diff --git a/spec/ruby/library/win32ole/win32ole_variable/to_s_spec.rb b/spec/ruby/library/win32ole/win32ole_variable/to_s_spec.rb index 000ac14d7e..d4cab8e924 100644 --- a/spec/ruby/library/win32ole/win32ole_variable/to_s_spec.rb +++ b/spec/ruby/library/win32ole/win32ole_variable/to_s_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" require_relative 'shared/name' platform_is :windows do diff --git a/spec/ruby/library/win32ole/win32ole_variable/value_spec.rb b/spec/ruby/library/win32ole/win32ole_variable/value_spec.rb index 4f240b561c..b7849793c5 100644 --- a/spec/ruby/library/win32ole/win32ole_variable/value_spec.rb +++ b/spec/ruby/library/win32ole/win32ole_variable/value_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require 'win32ole' diff --git a/spec/ruby/library/win32ole/win32ole_variable/variable_kind_spec.rb b/spec/ruby/library/win32ole/win32ole_variable/variable_kind_spec.rb index 4cca7f8874..7a79d32ddc 100644 --- a/spec/ruby/library/win32ole/win32ole_variable/variable_kind_spec.rb +++ b/spec/ruby/library/win32ole/win32ole_variable/variable_kind_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require 'win32ole' diff --git a/spec/ruby/library/win32ole/win32ole_variable/varkind_spec.rb b/spec/ruby/library/win32ole/win32ole_variable/varkind_spec.rb index 56cd1c337a..9d7b8238c8 100644 --- a/spec/ruby/library/win32ole/win32ole_variable/varkind_spec.rb +++ b/spec/ruby/library/win32ole/win32ole_variable/varkind_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require 'win32ole' diff --git a/spec/ruby/library/win32ole/win32ole_variable/visible_spec.rb b/spec/ruby/library/win32ole/win32ole_variable/visible_spec.rb index 7f7a557b57..60252e8139 100644 --- a/spec/ruby/library/win32ole/win32ole_variable/visible_spec.rb +++ b/spec/ruby/library/win32ole/win32ole_variable/visible_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" platform_is :windows do require 'win32ole' diff --git a/spec/ruby/library/zlib/gzipreader/each_line_spec.rb b/spec/ruby/library/zlib/gzipreader/each_line_spec.rb index efaf27d6bb..6f17365879 100644 --- a/spec/ruby/library/zlib/gzipreader/each_line_spec.rb +++ b/spec/ruby/library/zlib/gzipreader/each_line_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" require_relative 'shared/each' describe "Zlib::GzipReader#each_line" do diff --git a/spec/ruby/library/zlib/gzipreader/each_spec.rb b/spec/ruby/library/zlib/gzipreader/each_spec.rb index 59aa63e52c..3b98391a87 100644 --- a/spec/ruby/library/zlib/gzipreader/each_spec.rb +++ b/spec/ruby/library/zlib/gzipreader/each_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" require_relative 'shared/each' describe "Zlib::GzipReader#each" do diff --git a/spec/ruby/library/zlib/inflate/finish_spec.rb b/spec/ruby/library/zlib/inflate/finish_spec.rb index f6e592fb6b..3e0663e265 100644 --- a/spec/ruby/library/zlib/inflate/finish_spec.rb +++ b/spec/ruby/library/zlib/inflate/finish_spec.rb @@ -1,3 +1,4 @@ +require_relative "../../../spec_helper" require 'zlib' describe "Zlib::Inflate#finish" do diff --git a/spec/ruby/shared/kernel/at_exit.rb b/spec/ruby/shared/kernel/at_exit.rb new file mode 100644 index 0000000000..26ad361a5b --- /dev/null +++ b/spec/ruby/shared/kernel/at_exit.rb @@ -0,0 +1,67 @@ +describe :kernel_at_exit, shared: true do + it "runs after all other code" do + ruby_exe("#{@method} { print 5 }; print 6").should == "65" + end + + it "runs in reverse order of registration" do + code = "#{@method} { print 4 }; #{@method} { print 5 }; print 6; #{@method} { print 7 }" + ruby_exe(code).should == "6754" + end + + it "allows calling exit inside a handler" do + code = "#{@method} { print 3 }; #{@method} { print 4; exit; print 5 }; #{@method} { print 6 }" + ruby_exe(code).should == "643" + end + + it "gives access to the last raised exception - global variables $! and $@" do + code = <<-EOC + #{@method} { + puts "The exception matches: \#{$! == $exception && $@ == $exception.backtrace} (message=\#{$!.message})" + } + + begin + raise "foo" + rescue => $exception + raise + end + EOC + + result = ruby_exe(code, args: "2>&1", exit_status: 1) + result.lines.should.include?("The exception matches: true (message=foo)\n") + end + + it "both exceptions in a handler and in the main script are printed" do + code = "#{@method} { raise 'at_exit_error' }; raise 'main_script_error'" + result = ruby_exe(code, args: "2>&1", exit_status: 1) + result.should.include?('at_exit_error (RuntimeError)') + result.should.include?('main_script_error (RuntimeError)') + end + + it "decides the exit status if both at_exit and the main script raise SystemExit" do + ruby_exe("#{@method} { exit 43 }; exit 42", args: "2>&1", exit_status: 43) + $?.exitstatus.should == 43 + end + + it "runs all handlers even if some raise exceptions" do + code = "#{@method} { STDERR.puts 'last' }; #{@method} { exit 43 }; #{@method} { STDERR.puts 'first' }; exit 42" + result = ruby_exe(code, args: "2>&1", exit_status: 43) + result.should == "first\nlast\n" + $?.exitstatus.should == 43 + end + + it "runs handlers even if the main script fails to parse" do + script = fixture(__FILE__, "#{@method}.rb") + result = ruby_exe('{', options: "-r#{script}", args: "2>&1", exit_status: 1) + $?.should_not.success? + result.should.include?("handler ran\n") + result.should.include?("syntax error") + end + + it "calls the nested handler right after the outer one if a handler is nested into another handler" do + ruby_exe(<<~ruby).should == "last\nbefore\nafter\nnested\nfirst\n" + #{@method} { puts :first } + #{@method} { puts :before; #{@method} { puts :nested }; puts :after }; + #{@method} { puts :last } + ruby + end +end diff --git a/spec/ruby/shared/kernel/fixtures/END.rb b/spec/ruby/shared/kernel/fixtures/END.rb new file mode 100644 index 0000000000..cc8ac17c36 --- /dev/null +++ b/spec/ruby/shared/kernel/fixtures/END.rb @@ -0,0 +1,3 @@ +END { + STDERR.puts "handler ran" +} diff --git a/spec/ruby/shared/kernel/fixtures/at_exit.rb b/spec/ruby/shared/kernel/fixtures/at_exit.rb new file mode 100644 index 0000000000..e7bc8baf52 --- /dev/null +++ b/spec/ruby/shared/kernel/fixtures/at_exit.rb @@ -0,0 +1,3 @@ +at_exit do + STDERR.puts "handler ran" +end diff --git a/spec/ruby/shared/process/exit.rb b/spec/ruby/shared/process/exit.rb index 7d901f1f1e..1e073614a3 100644 --- a/spec/ruby/shared/process/exit.rb +++ b/spec/ruby/shared/process/exit.rb @@ -104,6 +104,12 @@ describe :process_exit!, shared: true do $?.exitstatus.should == 21 end + it "skips ensure clauses" do + out = ruby_exe("begin; STDERR.puts 'before'; #{@object}.send(:exit!, 21); ensure; STDERR.puts 'ensure'; end", args: '2>&1', exit_status: 21) + out.should == "before\n" + $?.exitstatus.should == 21 + end + it "overrides the original exception and exit status when called from #at_exit" do code = <<-RUBY at_exit do diff --git a/spec/ruby/shared/rational/Rational.rb b/spec/ruby/shared/rational/Rational.rb index 2dc49c869c..a56d027c96 100644 --- a/spec/ruby/shared/rational/Rational.rb +++ b/spec/ruby/shared/rational/Rational.rb @@ -85,6 +85,11 @@ describe :kernel_Rational, shared: true do end end + it "raises a ZeroDivisionError if the second argument is 0" do + -> { Rational(1, 0) }.should raise_error(ZeroDivisionError, "divided by 0") + -> { Rational(1, 0.0) }.should raise_error(ZeroDivisionError, "divided by 0") + end + it "raises a TypeError if the first argument is nil" do -> { Rational(nil) }.should raise_error(TypeError) end diff --git a/spec/ruby/shared/rational/truncate.rb b/spec/ruby/shared/rational/truncate.rb index 761dd3113a..682ba22c7c 100644 --- a/spec/ruby/shared/rational/truncate.rb +++ b/spec/ruby/shared/rational/truncate.rb @@ -17,6 +17,18 @@ describe :rational_truncate, shared: true do end end + describe "with an explicit precision = 0" do + it "returns an integer" do + @rational.truncate(0).should be_kind_of(Integer) + end + + it "returns the truncated value toward 0" do + @rational.truncate(0).should == 314 + Rational(1, 2).truncate(0).should == 0 + Rational(-1, 2).truncate(0).should == 0 + end + end + describe "with a precision < 0" do it "returns an integer" do @rational.truncate(-2).should be_kind_of(Integer) @@ -42,4 +54,18 @@ describe :rational_truncate, shared: true do @rational.truncate(3).should == Rational(62857, 200) end end + + describe "with an invalid valud for precision" do + it "raises a TypeError" do + -> { @rational.truncate(nil) }.should raise_error(TypeError, "not an integer") + -> { @rational.truncate(1.0) }.should raise_error(TypeError, "not an integer") + -> { @rational.truncate('') }.should raise_error(TypeError, "not an integer") + end + + it "does not call to_int on the argument" do + object = Object.new + object.should_not_receive(:to_int) + -> { @rational.truncate(object) }.should raise_error(TypeError, "not an integer") + end + end end -- cgit v1.2.1