From 1243255c3a36433041012b6107a5ac48658a0895 Mon Sep 17 00:00:00 2001 From: Benoit Daloze Date: Sat, 30 Nov 2019 21:26:52 +0100 Subject: Update to ruby/spec@4eec3dc --- spec/ruby/CONTRIBUTING.md | 8 ++ spec/ruby/README.md | 4 +- spec/ruby/core/array/drop_spec.rb | 18 ++++ spec/ruby/core/class/to_s_spec.rb | 23 ----- spec/ruby/core/data/constants_spec.rb | 15 ++++ spec/ruby/core/env/assoc_spec.rb | 2 +- spec/ruby/core/env/delete_spec.rb | 6 ++ spec/ruby/core/env/each_key_spec.rb | 2 +- spec/ruby/core/env/each_value_spec.rb | 2 +- spec/ruby/core/env/index_spec.rb | 6 ++ spec/ruby/core/env/keys_spec.rb | 4 +- spec/ruby/core/env/rehash_spec.rb | 6 ++ spec/ruby/core/env/replace_spec.rb | 50 +++++++++-- spec/ruby/core/env/shared/to_hash.rb | 13 ++- spec/ruby/core/env/shared/update.rb | 44 ++++++++-- spec/ruby/core/env/to_a_spec.rb | 5 +- spec/ruby/core/env/to_h_spec.rb | 5 ++ spec/ruby/core/env/values_at_spec.rb | 28 +++++- spec/ruby/core/env/values_spec.rb | 9 +- spec/ruby/core/exception/args_spec.rb | 5 -- spec/ruby/core/exception/arguments_spec.rb | 11 --- spec/ruby/core/exception/backtrace_spec.rb | 12 ++- spec/ruby/core/exception/case_compare_spec.rb | 36 +++++++- .../exception/destination_encoding_name_spec.rb | 18 +++- .../core/exception/destination_encoding_spec.rb | 18 +++- spec/ruby/core/exception/error_bytes_spec.rb | 9 +- spec/ruby/core/exception/error_char_spec.rb | 9 +- spec/ruby/core/exception/exception_spec.rb | 54 +++--------- spec/ruby/core/exception/hierarchy_spec.rb | 62 ++++++++++++++ spec/ruby/core/exception/interrupt_spec.rb | 6 -- spec/ruby/core/exception/readagain_bytes_spec.rb | 9 +- spec/ruby/core/exception/script_error_spec.rb | 15 ---- spec/ruby/core/exception/signal_exception_spec.rb | 51 +++++++++++ .../core/exception/source_encoding_name_spec.rb | 18 +++- spec/ruby/core/exception/source_encoding_spec.rb | 18 +++- spec/ruby/core/exception/standard_error_spec.rb | 61 +++---------- spec/ruby/core/exception/system_call_error_spec.rb | 69 ++++++++++++--- spec/ruby/core/exception/to_s_spec.rb | 16 +++- spec/ruby/core/file/ftype_spec.rb | 5 +- spec/ruby/core/file/lutime_spec.rb | 40 +++++++++ spec/ruby/core/file/open_spec.rb | 8 ++ spec/ruby/core/float/comparison_spec.rb | 32 +++++++ spec/ruby/core/integer/constants_spec.rb | 25 ++++++ spec/ruby/core/io/popen_spec.rb | 41 +++------ spec/ruby/core/kernel/rand_spec.rb | 10 +++ spec/ruby/core/kernel/shared/load.rb | 36 +++++++- spec/ruby/core/marshal/dump_spec.rb | 6 ++ spec/ruby/core/marshal/shared/load.rb | 13 +++ spec/ruby/core/matchdata/allocate_spec.rb | 10 +++ spec/ruby/core/matchdata/dup_spec.rb | 14 +++ spec/ruby/core/matchdata/regexp_spec.rb | 6 ++ spec/ruby/core/module/autoload_spec.rb | 21 +++++ .../fixtures/autoload_self_during_require.rb | 5 ++ spec/ruby/core/module/fixtures/classes.rb | 3 + spec/ruby/core/module/fixtures/multi/foo.rb | 6 ++ .../ruby/core/module/fixtures/multi/foo/bar_baz.rb | 11 +++ spec/ruby/core/module/shared/set_visibility.rb | 17 ++++ spec/ruby/core/module/to_s_spec.rb | 31 ++++++- spec/ruby/core/module/undef_method_spec.rb | 33 +++++++- spec/ruby/core/process/clock_getres_spec.rb | 5 +- spec/ruby/core/process/clock_gettime_spec.rb | 93 ++++++++++++++++++++ spec/ruby/core/process/exec_spec.rb | 33 +++++++- spec/ruby/core/process/fixtures/common.rb | 8 +- spec/ruby/core/process/status/equal_value_spec.rb | 12 ++- spec/ruby/core/process/status/exitstatus_spec.rb | 2 +- spec/ruby/core/process/status/termsig_spec.rb | 8 -- spec/ruby/core/process/status/to_i_spec.rb | 10 ++- spec/ruby/core/process/times_spec.rb | 26 +++--- spec/ruby/core/process/tms/cstime_spec.rb | 9 -- spec/ruby/core/process/tms/cutime_spec.rb | 9 -- .../core/process/tms/element_reference_spec.rb | 5 -- spec/ruby/core/process/tms/members_spec.rb | 5 -- spec/ruby/core/process/tms/new_spec.rb | 5 -- spec/ruby/core/process/tms/stime_spec.rb | 9 -- spec/ruby/core/process/tms/utime_spec.rb | 9 -- spec/ruby/core/regexp/match_spec.rb | 4 + spec/ruby/core/struct/clone_spec.rb | 7 ++ spec/ruby/core/struct/dup_spec.rb | 3 + .../ruby/core/struct/instance_variable_get_spec.rb | 16 ++++ spec/ruby/core/struct/new_spec.rb | 25 +++++- spec/ruby/core/struct/shared/dup.rb | 9 ++ spec/ruby/core/time/new_spec.rb | 6 ++ spec/ruby/fixtures/code/wrap_fixture.rb | 8 +- spec/ruby/language/match_spec.rb | 7 ++ spec/ruby/language/regexp/encoding_spec.rb | 16 ++++ spec/ruby/library/base64/decode64_spec.rb | 16 ++++ spec/ruby/library/base64/encode64_spec.rb | 9 ++ spec/ruby/library/base64/strict_decode64_spec.rb | 41 +++++++++ spec/ruby/library/base64/strict_encode64_spec.rb | 19 +++++ spec/ruby/library/bigdecimal/BigDecimal_spec.rb | 99 +++++++++++++++++++++- spec/ruby/library/conditionvariable/signal_spec.rb | 35 ++++++++ spec/ruby/library/coverage/result_spec.rb | 5 +- spec/ruby/library/date/iso8601_spec.rb | 7 ++ spec/ruby/library/date/rfc3339_spec.rb | 13 +++ spec/ruby/library/mkmf/mkmf_spec.rb | 7 ++ spec/ruby/library/rbconfig/rbconfig_spec.rb | 12 +++ spec/ruby/library/rbconfig/sizeof/limits_spec.rb | 42 +++++++++ .../library/rbconfig/unicode_emoji_version_spec.rb | 22 +++++ spec/ruby/library/rbconfig/unicode_version_spec.rb | 34 ++++++++ spec/ruby/library/scanf/io/scanf_spec.rb | 4 +- spec/ruby/library/scanf/io/shared/block_scanf.rb | 2 +- .../socket/basicsocket/read_nonblock_spec.rb | 46 ++++++++++ .../socket/basicsocket/write_nonblock_spec.rb | 45 ++++++++++ spec/ruby/library/socket/tcpserver/new_spec.rb | 35 ++++++++ spec/ruby/library/uri/select_spec.rb | 8 +- .../library/win32ole/win32ole_type/new_spec.rb | 15 ++-- spec/ruby/library/zlib/deflate/append_spec.rb | 1 - spec/ruby/library/zlib/deflate/flush_spec.rb | 1 - spec/ruby/library/zlib/deflate_spec.rb | 2 +- spec/ruby/library/zlib/gunzip_spec.rb | 14 +++ spec/ruby/library/zlib/gzip_spec.rb | 15 ++++ spec/ruby/library/zlib/gzipfile/crc_spec.rb | 1 - spec/ruby/library/zlib/gzipfile/finish_spec.rb | 1 - spec/ruby/library/zlib/gzipfile/level_spec.rb | 1 - spec/ruby/library/zlib/gzipfile/mtime_spec.rb | 1 - spec/ruby/library/zlib/gzipfile/os_code_spec.rb | 1 - spec/ruby/library/zlib/gzipfile/sync_spec.rb | 1 - spec/ruby/library/zlib/gzipfile/to_io_spec.rb | 1 - spec/ruby/library/zlib/gzipfile/wrap_spec.rb | 1 - .../ruby/library/zlib/gzipreader/each_byte_spec.rb | 2 +- .../ruby/library/zlib/gzipreader/each_line_spec.rb | 2 +- spec/ruby/library/zlib/gzipreader/each_spec.rb | 2 +- spec/ruby/library/zlib/gzipreader/eof_spec.rb | 6 +- spec/ruby/library/zlib/gzipreader/getc_spec.rb | 4 +- spec/ruby/library/zlib/gzipreader/gets_spec.rb | 2 +- spec/ruby/library/zlib/gzipreader/lineno_spec.rb | 1 - spec/ruby/library/zlib/gzipreader/open_spec.rb | 1 - spec/ruby/library/zlib/gzipreader/pos_spec.rb | 4 +- spec/ruby/library/zlib/gzipreader/read_spec.rb | 4 +- spec/ruby/library/zlib/gzipreader/readchar_spec.rb | 1 - spec/ruby/library/zlib/gzipreader/readline_spec.rb | 1 - .../ruby/library/zlib/gzipreader/readlines_spec.rb | 1 - .../library/zlib/gzipreader/readpartial_spec.rb | 2 +- spec/ruby/library/zlib/gzipreader/rewind_spec.rb | 3 +- spec/ruby/library/zlib/gzipreader/shared/each.rb | 2 - spec/ruby/library/zlib/gzipreader/tell_spec.rb | 1 - .../ruby/library/zlib/gzipreader/ungetbyte_spec.rb | 2 +- spec/ruby/library/zlib/gzipreader/ungetc_spec.rb | 2 +- spec/ruby/library/zlib/gzipreader/unused_spec.rb | 1 - spec/ruby/library/zlib/gzipwriter/comment_spec.rb | 1 - spec/ruby/library/zlib/gzipwriter/flush_spec.rb | 1 - spec/ruby/library/zlib/gzipwriter/new_spec.rb | 1 - spec/ruby/library/zlib/gzipwriter/open_spec.rb | 1 - .../ruby/library/zlib/gzipwriter/orig_name_spec.rb | 1 - spec/ruby/library/zlib/gzipwriter/pos_spec.rb | 1 - spec/ruby/library/zlib/gzipwriter/print_spec.rb | 1 - spec/ruby/library/zlib/gzipwriter/printf_spec.rb | 1 - spec/ruby/library/zlib/gzipwriter/putc_spec.rb | 1 - spec/ruby/library/zlib/gzipwriter/puts_spec.rb | 1 - spec/ruby/library/zlib/gzipwriter/tell_spec.rb | 1 - spec/ruby/library/zlib/gzipwriter/write_spec.rb | 2 +- spec/ruby/library/zlib/inflate/sync_point_spec.rb | 1 - spec/ruby/library/zlib/inflate/sync_spec.rb | 1 - spec/ruby/library/zlib/inflate_spec.rb | 2 +- spec/ruby/library/zlib/zlib_version_spec.rb | 7 ++ spec/ruby/library/zlib/zstream/close_spec.rb | 1 - spec/ruby/library/zlib/zstream/closed_spec.rb | 1 - spec/ruby/library/zlib/zstream/end_spec.rb | 1 - spec/ruby/library/zlib/zstream/ended_spec.rb | 1 - spec/ruby/library/zlib/zstream/finish_spec.rb | 1 - spec/ruby/library/zlib/zstream/finished_spec.rb | 1 - .../library/zlib/zstream/flush_next_in_spec.rb | 1 - spec/ruby/library/zlib/zstream/reset_spec.rb | 1 - spec/ruby/library/zlib/zstream/stream_end_spec.rb | 1 - spec/ruby/library/zlib/zstream/total_in_spec.rb | 1 - spec/ruby/library/zlib/zstream/total_out_spec.rb | 1 - spec/ruby/optional/capi/array_spec.rb | 8 ++ spec/ruby/optional/capi/ext/array_spec.c | 14 +++ spec/ruby/optional/capi/ext/gc_spec.c | 5 ++ spec/ruby/optional/capi/ext/kernel_spec.c | 9 ++ spec/ruby/optional/capi/ext/string_spec.c | 15 ++++ spec/ruby/optional/capi/gc_spec.rb | 11 ++- spec/ruby/optional/capi/kernel_spec.rb | 5 ++ spec/ruby/optional/capi/string_spec.rb | 24 ++++++ 174 files changed, 1775 insertions(+), 421 deletions(-) delete mode 100644 spec/ruby/core/class/to_s_spec.rb create mode 100644 spec/ruby/core/data/constants_spec.rb delete mode 100644 spec/ruby/core/exception/args_spec.rb delete mode 100644 spec/ruby/core/exception/arguments_spec.rb create mode 100644 spec/ruby/core/exception/hierarchy_spec.rb delete mode 100644 spec/ruby/core/exception/script_error_spec.rb create mode 100644 spec/ruby/core/file/lutime_spec.rb create mode 100644 spec/ruby/core/integer/constants_spec.rb create mode 100644 spec/ruby/core/matchdata/allocate_spec.rb create mode 100644 spec/ruby/core/matchdata/dup_spec.rb create mode 100644 spec/ruby/core/module/fixtures/autoload_self_during_require.rb create mode 100644 spec/ruby/core/module/fixtures/multi/foo.rb create mode 100644 spec/ruby/core/module/fixtures/multi/foo/bar_baz.rb delete mode 100644 spec/ruby/core/process/tms/cstime_spec.rb delete mode 100644 spec/ruby/core/process/tms/cutime_spec.rb delete mode 100644 spec/ruby/core/process/tms/element_reference_spec.rb delete mode 100644 spec/ruby/core/process/tms/members_spec.rb delete mode 100644 spec/ruby/core/process/tms/new_spec.rb delete mode 100644 spec/ruby/core/process/tms/stime_spec.rb delete mode 100644 spec/ruby/core/process/tms/utime_spec.rb create mode 100644 spec/ruby/core/struct/clone_spec.rb create mode 100644 spec/ruby/core/struct/instance_variable_get_spec.rb create mode 100644 spec/ruby/core/struct/shared/dup.rb create mode 100644 spec/ruby/library/base64/strict_decode64_spec.rb create mode 100644 spec/ruby/library/base64/strict_encode64_spec.rb create mode 100644 spec/ruby/library/date/rfc3339_spec.rb create mode 100644 spec/ruby/library/mkmf/mkmf_spec.rb create mode 100644 spec/ruby/library/rbconfig/sizeof/limits_spec.rb create mode 100644 spec/ruby/library/rbconfig/unicode_emoji_version_spec.rb create mode 100644 spec/ruby/library/rbconfig/unicode_version_spec.rb create mode 100644 spec/ruby/library/socket/basicsocket/read_nonblock_spec.rb create mode 100644 spec/ruby/library/socket/basicsocket/write_nonblock_spec.rb delete mode 100644 spec/ruby/library/zlib/deflate/append_spec.rb delete mode 100644 spec/ruby/library/zlib/deflate/flush_spec.rb create mode 100644 spec/ruby/library/zlib/gunzip_spec.rb create mode 100644 spec/ruby/library/zlib/gzip_spec.rb delete mode 100644 spec/ruby/library/zlib/gzipfile/crc_spec.rb delete mode 100644 spec/ruby/library/zlib/gzipfile/finish_spec.rb delete mode 100644 spec/ruby/library/zlib/gzipfile/level_spec.rb delete mode 100644 spec/ruby/library/zlib/gzipfile/mtime_spec.rb delete mode 100644 spec/ruby/library/zlib/gzipfile/os_code_spec.rb delete mode 100644 spec/ruby/library/zlib/gzipfile/sync_spec.rb delete mode 100644 spec/ruby/library/zlib/gzipfile/to_io_spec.rb delete mode 100644 spec/ruby/library/zlib/gzipfile/wrap_spec.rb delete mode 100644 spec/ruby/library/zlib/gzipreader/lineno_spec.rb delete mode 100644 spec/ruby/library/zlib/gzipreader/open_spec.rb delete mode 100644 spec/ruby/library/zlib/gzipreader/readchar_spec.rb delete mode 100644 spec/ruby/library/zlib/gzipreader/readline_spec.rb delete mode 100644 spec/ruby/library/zlib/gzipreader/readlines_spec.rb delete mode 100644 spec/ruby/library/zlib/gzipreader/tell_spec.rb delete mode 100644 spec/ruby/library/zlib/gzipreader/unused_spec.rb delete mode 100644 spec/ruby/library/zlib/gzipwriter/comment_spec.rb delete mode 100644 spec/ruby/library/zlib/gzipwriter/flush_spec.rb delete mode 100644 spec/ruby/library/zlib/gzipwriter/new_spec.rb delete mode 100644 spec/ruby/library/zlib/gzipwriter/open_spec.rb delete mode 100644 spec/ruby/library/zlib/gzipwriter/orig_name_spec.rb delete mode 100644 spec/ruby/library/zlib/gzipwriter/pos_spec.rb delete mode 100644 spec/ruby/library/zlib/gzipwriter/print_spec.rb delete mode 100644 spec/ruby/library/zlib/gzipwriter/printf_spec.rb delete mode 100644 spec/ruby/library/zlib/gzipwriter/putc_spec.rb delete mode 100644 spec/ruby/library/zlib/gzipwriter/puts_spec.rb delete mode 100644 spec/ruby/library/zlib/gzipwriter/tell_spec.rb delete mode 100644 spec/ruby/library/zlib/inflate/sync_point_spec.rb delete mode 100644 spec/ruby/library/zlib/inflate/sync_spec.rb delete mode 100644 spec/ruby/library/zlib/zstream/close_spec.rb delete mode 100644 spec/ruby/library/zlib/zstream/closed_spec.rb delete mode 100644 spec/ruby/library/zlib/zstream/end_spec.rb delete mode 100644 spec/ruby/library/zlib/zstream/ended_spec.rb delete mode 100644 spec/ruby/library/zlib/zstream/finish_spec.rb delete mode 100644 spec/ruby/library/zlib/zstream/finished_spec.rb delete mode 100644 spec/ruby/library/zlib/zstream/flush_next_in_spec.rb delete mode 100644 spec/ruby/library/zlib/zstream/reset_spec.rb delete mode 100644 spec/ruby/library/zlib/zstream/stream_end_spec.rb delete mode 100644 spec/ruby/library/zlib/zstream/total_in_spec.rb delete mode 100644 spec/ruby/library/zlib/zstream/total_out_spec.rb (limited to 'spec/ruby') diff --git a/spec/ruby/CONTRIBUTING.md b/spec/ruby/CONTRIBUTING.md index 2f9b138372..1ec6f0ff4b 100644 --- a/spec/ruby/CONTRIBUTING.md +++ b/spec/ruby/CONTRIBUTING.md @@ -88,6 +88,14 @@ Array.should have_method(:new) raise "oops" }.should raise_error(RuntimeError, /oops/) +-> { + raise "oops" +}.should raise_error(RuntimeError) { |e| + # Custom checks on the Exception object + e.message.should include("oops") + e.cause.should == nil +} + # To avoid! Instead, use an expectation testing what the code in the lambda does. # If an exception is raised, it will fail the example anyway. -> { ... }.should_not raise_error diff --git a/spec/ruby/README.md b/spec/ruby/README.md index 980eaf034f..3163a78902 100644 --- a/spec/ruby/README.md +++ b/spec/ruby/README.md @@ -1,7 +1,7 @@ # The Ruby Spec Suite -[![Build Status](https://travis-ci.org/ruby/spec.svg)](https://travis-ci.org/ruby/spec) -[![Build Status](https://ci.appveyor.com/api/projects/status/1gs6f399320o44b1?svg=true)](https://ci.appveyor.com/project/eregon/spec-x948i) +[![Actions Build Status](https://github.com/ruby/spec/workflows/CI/badge.svg?branch=master)](https://github.com/ruby/spec/actions) +[![Windows Actions Build Status](https://github.com/ruby/spec/workflows/Windows/badge.svg?branch=master)](https://github.com/ruby/spec/actions) [![Gitter](https://badges.gitter.im/ruby/spec.svg)](https://gitter.im/ruby/spec) The Ruby Spec Suite, abbreviated `ruby/spec`, is a test suite for the behavior of the Ruby programming language. diff --git a/spec/ruby/core/array/drop_spec.rb b/spec/ruby/core/array/drop_spec.rb index 89b8534af4..84ea86b04c 100644 --- a/spec/ruby/core/array/drop_spec.rb +++ b/spec/ruby/core/array/drop_spec.rb @@ -30,4 +30,22 @@ describe "Array#drop" do ary.shift ary.drop(1).should == [2] end + + it "tries to convert the passed argument to an Integer using #to_int" do + obj = mock("to_int") + obj.should_receive(:to_int).and_return(2) + + [1, 2, 3].drop(obj).should == [3] + end + + it "raises a TypeError when the passed argument can't be coerced to Integer" do + -> { [1, 2].drop("cat") }.should raise_error(TypeError) + end + + it "raises a TypeError when the passed argument isn't an integer and #to_int returns non-Integer" do + obj = mock("to_int") + obj.should_receive(:to_int).and_return("cat") + + -> { [1, 2].drop(obj) }.should raise_error(TypeError) + end end diff --git a/spec/ruby/core/class/to_s_spec.rb b/spec/ruby/core/class/to_s_spec.rb deleted file mode 100644 index 2055593a03..0000000000 --- a/spec/ruby/core/class/to_s_spec.rb +++ /dev/null @@ -1,23 +0,0 @@ -require_relative '../../spec_helper' -require_relative 'fixtures/classes' - -describe "Class#to_s" do - it 'regular class returns same name as Module#to_s' do - String.to_s.should == 'String' - end - - describe 'singleton class' do - it 'for modules includes module name' do - CoreClassSpecs.singleton_class.to_s.should == '#' - end - - it 'for classes includes class name' do - CoreClassSpecs::Record.singleton_class.to_s.should == '#' - end - - it 'for objects includes class name and object ID' do - obj = CoreClassSpecs::Record.new - obj.singleton_class.to_s.should =~ /#>/ - end - end -end diff --git a/spec/ruby/core/data/constants_spec.rb b/spec/ruby/core/data/constants_spec.rb new file mode 100644 index 0000000000..1b4c0d2df3 --- /dev/null +++ b/spec/ruby/core/data/constants_spec.rb @@ -0,0 +1,15 @@ +require_relative '../../spec_helper' + +describe "Data" do + it "is a subclass of Object" do + suppress_warning do + Data.superclass.should == Object + end + end + + ruby_version_is "2.5" do + it "is deprecated" do + -> { Data }.should complain(/constant ::Data is deprecated/) + end + end +end diff --git a/spec/ruby/core/env/assoc_spec.rb b/spec/ruby/core/env/assoc_spec.rb index 9946e328a9..c7a388db75 100644 --- a/spec/ruby/core/env/assoc_spec.rb +++ b/spec/ruby/core/env/assoc_spec.rb @@ -26,6 +26,6 @@ describe "ENV.assoc" do end it "raises TypeError if the argument is not a String and does not respond to #to_str" do - -> { ENV.assoc(Object.new) }.should raise_error(TypeError) + -> { ENV.assoc(Object.new) }.should raise_error(TypeError, "no implicit conversion of Object into String") end end diff --git a/spec/ruby/core/env/delete_spec.rb b/spec/ruby/core/env/delete_spec.rb index e875df4aeb..b7fe1ee675 100644 --- a/spec/ruby/core/env/delete_spec.rb +++ b/spec/ruby/core/env/delete_spec.rb @@ -30,6 +30,12 @@ describe "ENV.delete" do ScratchPad.recorded.should == "foo" end + it "does not evaluate the block if the envirionment variable exists" do + ENV["foo"] = "bar" + ENV.delete("foo") { |name| fail "Should not happen" } + ENV["foo"].should == nil + end + it "raises TypeError if the argument is not a String and does not respond to #to_str" do -> { ENV.delete(Object.new) }.should raise_error(TypeError, "no implicit conversion of Object into String") end diff --git a/spec/ruby/core/env/each_key_spec.rb b/spec/ruby/core/env/each_key_spec.rb index 5c5cf4f80e..0efcb09900 100644 --- a/spec/ruby/core/env/each_key_spec.rb +++ b/spec/ruby/core/env/each_key_spec.rb @@ -10,7 +10,7 @@ describe "ENV.each_key" do ENV.clear ENV["1"] = "3" ENV["2"] = "4" - ENV.each_key { |k| e << k } + ENV.each_key { |k| e << k }.should equal(ENV) e.should include("1") e.should include("2") ensure diff --git a/spec/ruby/core/env/each_value_spec.rb b/spec/ruby/core/env/each_value_spec.rb index ea29b3a0d7..60d9f605d8 100644 --- a/spec/ruby/core/env/each_value_spec.rb +++ b/spec/ruby/core/env/each_value_spec.rb @@ -10,7 +10,7 @@ describe "ENV.each_value" do ENV.clear ENV["1"] = "3" ENV["2"] = "4" - ENV.each_value { |v| e << v } + ENV.each_value { |v| e << v }.should equal(ENV) e.should include("3") e.should include("4") ensure diff --git a/spec/ruby/core/env/index_spec.rb b/spec/ruby/core/env/index_spec.rb index 04986a0421..43875f5a50 100644 --- a/spec/ruby/core/env/index_spec.rb +++ b/spec/ruby/core/env/index_spec.rb @@ -3,4 +3,10 @@ require_relative 'shared/key' describe "ENV.index" do it_behaves_like :env_key, :index + + it "warns about deprecation" do + -> do + ENV.index("foo") + end.should complain(/warning: ENV.index is deprecated; use ENV.key/) + end end diff --git a/spec/ruby/core/env/keys_spec.rb b/spec/ruby/core/env/keys_spec.rb index 3699b2c225..b074a8f7c7 100644 --- a/spec/ruby/core/env/keys_spec.rb +++ b/spec/ruby/core/env/keys_spec.rb @@ -2,8 +2,8 @@ require_relative '../../spec_helper' describe "ENV.keys" do - it "returns all the keys" do - ENV.keys.sort.should == ENV.to_hash.keys.sort + it "returns an array of the keys" do + ENV.keys.should == ENV.to_hash.keys end it "returns the keys in the locale encoding" do diff --git a/spec/ruby/core/env/rehash_spec.rb b/spec/ruby/core/env/rehash_spec.rb index e724feaa39..3782e4b727 100644 --- a/spec/ruby/core/env/rehash_spec.rb +++ b/spec/ruby/core/env/rehash_spec.rb @@ -1 +1,7 @@ require_relative '../../spec_helper' + +describe "ENV.rehash" do + it "returns nil" do + ENV.rehash.should == nil + end +end diff --git a/spec/ruby/core/env/replace_spec.rb b/spec/ruby/core/env/replace_spec.rb index 8837deea4a..9fc67643d1 100644 --- a/spec/ruby/core/env/replace_spec.rb +++ b/spec/ruby/core/env/replace_spec.rb @@ -1,15 +1,51 @@ require_relative '../../spec_helper' describe "ENV.replace" do + before :each do + @orig = ENV.to_hash + ENV.delete("foo") + end + + after :each do + ENV.replace(@orig) + end it "replaces ENV with a Hash" do - ENV["foo"] = "bar" - e = ENV.reject { |k, v| k == "foo" } - e["baz"] = "bam" - ENV.replace e - ENV["foo"].should == nil - ENV["baz"].should == "bam" - ENV.delete "baz" + ENV.replace("foo" => "0", "bar" => "1").should equal(ENV) + ENV.size.should == 2 + ENV["foo"].should == "0" + ENV["bar"].should == "1" + end + + it "raises TypeError if the argument is not a Hash" do + -> { ENV.replace(Object.new) }.should raise_error(TypeError, "no implicit conversion of Object into Hash") + ENV.to_hash.should == @orig + end + + it "raises TypeError if a key is not a String" do + -> { ENV.replace(Object.new => "0") }.should raise_error(TypeError, "no implicit conversion of Object into String") + ENV.to_hash.should == @orig + end + + it "raises TypeError if a value is not a String" do + -> { ENV.replace("foo" => Object.new) }.should raise_error(TypeError, "no implicit conversion of Object into String") + ENV.to_hash.should == @orig + end + + it "raises Errno::EINVAL when the key contains the '=' character" do + -> { ENV.replace("foo=" =>"bar") }.should raise_error(Errno::EINVAL) + end + + it "raises Errno::EINVAL when the key is an empty string" do + -> { ENV.replace("" => "bar") }.should raise_error(Errno::EINVAL) + end + + it "does not accept good data preceding an error" do + -> { ENV.replace("foo" => "1", Object.new => Object.new) }.should raise_error(TypeError, "no implicit conversion of Object into String") end + it "does not accept good data following an error" do + -> { ENV.replace(Object.new => Object.new, "foo" => "0") }.should raise_error(TypeError, "no implicit conversion of Object into String") + ENV.to_hash.should == @orig + end end diff --git a/spec/ruby/core/env/shared/to_hash.rb b/spec/ruby/core/env/shared/to_hash.rb index 254054c14d..bfa5699e8d 100644 --- a/spec/ruby/core/env/shared/to_hash.rb +++ b/spec/ruby/core/env/shared/to_hash.rb @@ -1,10 +1,17 @@ describe :env_to_hash, shared: true do + before :each do + @saved_foo = ENV["foo"] + end + + after :each do + ENV["foo"]= @saved_foo + end + it "returns the ENV as a hash" do ENV["foo"] = "bar" h = ENV.send(@method) h.should be_an_instance_of(Hash) h["foo"].should == "bar" - ENV.delete "foo" end it "uses the locale encoding for keys" do @@ -18,5 +25,9 @@ describe :env_to_hash, shared: true do it "duplicates the ENV when converting to a Hash" do h = ENV.send(@method) h.should_not equal ENV + h.size.should == ENV.size + h.each_pair do |k, v| + ENV[k].should == v + end end end diff --git a/spec/ruby/core/env/shared/update.rb b/spec/ruby/core/env/shared/update.rb index 430cda5185..129a56544c 100644 --- a/spec/ruby/core/env/shared/update.rb +++ b/spec/ruby/core/env/shared/update.rb @@ -9,8 +9,8 @@ describe :env_update, shared: true do ENV["bar"] = @saved_bar end - it "adds the parameter hash to ENV" do - ENV.send @method, {"foo" => "0", "bar" => "1"} + it "adds the parameter hash to ENV, returning ENV" do + ENV.send(@method, "foo" => "0", "bar" => "1").should equal(ENV) ENV["foo"].should == "0" ENV["bar"].should == "1" end @@ -19,17 +19,43 @@ describe :env_update, shared: true do ENV.send(@method, {"foo" => "0", "bar" => "1"}).should equal(ENV) end - it "yields key, the old value and the new value when replacing entries" do + it "yields key, the old value and the new value when replacing an entry" do ENV.send @method, {"foo" => "0", "bar" => "3"} a = [] ENV.send @method, {"foo" => "1", "bar" => "4"} do |key, old, new| a << [key, old, new] + new + end + a[0].should == ["foo", "0", "1"] + a[1].should == ["bar", "3", "4"] + end + + it "yields key, the old value and the new value when replacing an entry" do + ENV.send @method, {"foo" => "0", "bar" => "3"} + ENV.send @method, {"foo" => "1", "bar" => "4"} do |key, old, new| (new.to_i + 1).to_s end ENV["foo"].should == "2" ENV["bar"].should == "5" - a[0].should == ["foo", "0", "1"] - a[1].should == ["bar", "3", "4"] + end + + ruby_version_is "2.7" do + # BUG: https://bugs.ruby-lang.org/issues/16192 + it "does not evaluate the block when the name is new" do + ENV.delete("bar") + ENV.send @method, {"foo" => "0"} + ENV.send(@method, "bar" => "1") { |key, old, new| fail "Should not get here" } + ENV["bar"].should == "1" + end + + # BUG: https://bugs.ruby-lang.org/issues/16192 + it "does not use the block's return value as the value when the name is new" do + ENV.delete("bar") + ENV.send @method, {"foo" => "0"} + ENV.send(@method, "bar" => "1") { |key, old, new| "Should not use this value" } + ENV["foo"].should == "0" + ENV["bar"].should == "1" + end end it "returns ENV when block given" do @@ -44,6 +70,14 @@ describe :env_update, shared: true do -> { ENV.send @method, "foo" => Object.new }.should raise_error(TypeError, "no implicit conversion of Object into String") end + it "raises Errno::EINVAL when a name contains the '=' character" do + -> { ENV.send(@method, "foo=" => "bar") }.should raise_error(Errno::EINVAL) + end + + it "raises Errno::EINVAL when a name is an empty string" do + -> { ENV.send(@method, "" => "bar") }.should raise_error(Errno::EINVAL) + end + it "updates good data preceding an error" do ENV["foo"] = "0" begin diff --git a/spec/ruby/core/env/to_a_spec.rb b/spec/ruby/core/env/to_a_spec.rb index ed290a48a5..25441eb029 100644 --- a/spec/ruby/core/env/to_a_spec.rb +++ b/spec/ruby/core/env/to_a_spec.rb @@ -3,11 +3,10 @@ require_relative '../../spec_helper' describe "ENV.to_a" do it "returns the ENV as an array" do - ENV["foo"] = "bar" a = ENV.to_a a.is_a?(Array).should == true - a.find { |e| e.first == "foo" }.should == ["foo", "bar"] - ENV.delete "foo" + a.size.should == ENV.size + ENV.each_pair { |k, v| a.should include([k, v])} end it "returns the entries in the locale encoding" do diff --git a/spec/ruby/core/env/to_h_spec.rb b/spec/ruby/core/env/to_h_spec.rb index 81a17700e9..822167aa2b 100644 --- a/spec/ruby/core/env/to_h_spec.rb +++ b/spec/ruby/core/env/to_h_spec.rb @@ -19,6 +19,11 @@ describe "ENV.to_h" do ENV.to_h { |k, v| [k, v.upcase] }.should == { 'a' => "B", 'c' => "D" } end + it "does not require the array elements to be strings" do + ENV.replace("a" => "b", "c" => "d") + ENV.to_h { |k, v| [k.to_sym, v.to_sym] }.should == { :a => :b, :c => :d } + end + it "raises ArgumentError if block returns longer or shorter array" do -> do ENV.to_h { |k, v| [k, v.upcase, 1] } diff --git a/spec/ruby/core/env/values_at_spec.rb b/spec/ruby/core/env/values_at_spec.rb index 906d8b01f2..ee970e5f65 100644 --- a/spec/ruby/core/env/values_at_spec.rb +++ b/spec/ruby/core/env/values_at_spec.rb @@ -1,17 +1,37 @@ require_relative '../../spec_helper' describe "ENV.values_at" do + before :each do + @saved_foo = ENV["foo"] + @saved_bar = ENV["bar"] + end + + after :each do + ENV["foo"] = @saved_foo + ENV["bar"] = @saved_bar + end - it "returns an array of the values referenced by the parameters as keys" do + it "returns an array of the values corresponding to the given keys" do ENV["foo"] = "oof" ENV["bar"] = "rab" - ENV.values_at.should == [] ENV.values_at("bar", "foo").should == ["rab", "oof"] - ENV.delete "foo" - ENV.delete "bar" + end + + it "returns an empty array if no keys specified" do + ENV.values_at.should == [] + end + + it "returns nil for each key that is not a name" do + ENV["foo"] = "oof" + ENV["bar"] = "rab" + ENV.values_at("x", "bar", "y", "foo", "z").should == [nil, "rab", nil, "oof", nil] end it "uses the locale encoding" do ENV.values_at(ENV.keys.first).first.encoding.should == Encoding.find('locale') end + + it "raises TypeError when a key is not coercible to String" do + -> { ENV.values_at("foo", Object.new) }.should raise_error(TypeError, "no implicit conversion of Object into String") + end end diff --git a/spec/ruby/core/env/values_spec.rb b/spec/ruby/core/env/values_spec.rb index 2e4e69c23b..919d7ffb7c 100644 --- a/spec/ruby/core/env/values_spec.rb +++ b/spec/ruby/core/env/values_spec.rb @@ -3,14 +3,7 @@ require_relative '../../spec_helper' describe "ENV.values" do it "returns an array of the values" do - orig = ENV.to_hash - begin - ENV.replace "a" => "b", "c" => "d" - a = ENV.values - a.sort.should == ["b", "d"] - ensure - ENV.replace orig - end + ENV.values.should == ENV.to_hash.values end it "uses the locale encoding" do diff --git a/spec/ruby/core/exception/args_spec.rb b/spec/ruby/core/exception/args_spec.rb deleted file mode 100644 index 005c2dd198..0000000000 --- a/spec/ruby/core/exception/args_spec.rb +++ /dev/null @@ -1,5 +0,0 @@ -require_relative '../../spec_helper' - -describe "NoMethodError#args" do - it "needs to be reviewed for spec completeness" -end diff --git a/spec/ruby/core/exception/arguments_spec.rb b/spec/ruby/core/exception/arguments_spec.rb deleted file mode 100644 index 0b283e9a54..0000000000 --- a/spec/ruby/core/exception/arguments_spec.rb +++ /dev/null @@ -1,11 +0,0 @@ -require_relative '../../spec_helper' - -describe "ArgumentError" do - it "is a subclass of StandardError" do - StandardError.should be_ancestor_of(ArgumentError) - end - - it "gives its own class name as message if it has no message" do - ArgumentError.new.message.should == "ArgumentError" - end -end diff --git a/spec/ruby/core/exception/backtrace_spec.rb b/spec/ruby/core/exception/backtrace_spec.rb index 5e140f8d9b..2d6825180a 100644 --- a/spec/ruby/core/exception/backtrace_spec.rb +++ b/spec/ruby/core/exception/backtrace_spec.rb @@ -47,7 +47,7 @@ describe "Exception#backtrace" do end end - it "produces a backtrace for an exception captured using $!" do + it "captures the backtrace for an exception into $!" do exception = begin raise rescue RuntimeError @@ -57,6 +57,16 @@ describe "Exception#backtrace" do exception.backtrace.first.should =~ /backtrace_spec/ end + it "captures the backtrace for an exception into $@" do + backtrace = begin + raise + rescue RuntimeError + $@ + end + + backtrace.first.should =~ /backtrace_spec/ + end + it "returns an Array that can be updated" do begin raise diff --git a/spec/ruby/core/exception/case_compare_spec.rb b/spec/ruby/core/exception/case_compare_spec.rb index a4c9eaa6bf..87b9dee3ca 100644 --- a/spec/ruby/core/exception/case_compare_spec.rb +++ b/spec/ruby/core/exception/case_compare_spec.rb @@ -1,5 +1,39 @@ require_relative '../../spec_helper' describe "SystemCallError.===" do - it "needs to be reviewed for spec completeness" + before :all do + @example_errno_class = Errno::EINVAL + @example_errno = @example_errno_class::Errno + end + + it "returns true for an instance of the same class" do + Errno::EINVAL.should === Errno::EINVAL.new + end + + it "returns true if errnos same" do + e = SystemCallError.new('foo', @example_errno) + @example_errno_class.===(e).should == true + end + + it "returns false if errnos different" do + e = SystemCallError.new('foo', @example_errno + 1) + @example_errno_class.===(e).should == false + end + + it "returns false if arg is not kind of SystemCallError" do + e = Object.new + @example_errno_class.===(e).should == false + end + + it "returns true if receiver is generic and arg is kind of SystemCallError" do + unknown_error_number = Errno.constants.size + e = SystemCallError.new('foo', @example_errno) + SystemCallError.===(e).should == true + end + + it "returns false if receiver is generic and arg is not kind of SystemCallError" do + unknown_error_number = Errno.constants.size + e = Object.new + SystemCallError.===(e).should == false + end end diff --git a/spec/ruby/core/exception/destination_encoding_name_spec.rb b/spec/ruby/core/exception/destination_encoding_name_spec.rb index b6ffff8c9c..a9e6474974 100644 --- a/spec/ruby/core/exception/destination_encoding_name_spec.rb +++ b/spec/ruby/core/exception/destination_encoding_name_spec.rb @@ -1,9 +1,23 @@ require_relative '../../spec_helper' describe "Encoding::UndefinedConversionError#destination_encoding_name" do - it "needs to be reviewed for spec completeness" + it "returns the destination encoding name" do + ec = Encoding::Converter.new("ISO-8859-1", "EUC-JP") + begin + ec.convert("\xa0") + rescue Encoding::UndefinedConversionError => e + e.destination_encoding_name.should == "EUC-JP" + end + end end describe "Encoding::InvalidByteSequenceError#destination_encoding_name" do - it "needs to be reviewed for spec completeness" + it "returns the destination encoding name" do + ec = Encoding::Converter.new("EUC-JP", "ISO-8859-1") + begin + ec.convert("\xa0") + rescue Encoding::InvalidByteSequenceError => e + e.destination_encoding_name.should == "UTF-8" + end + end end diff --git a/spec/ruby/core/exception/destination_encoding_spec.rb b/spec/ruby/core/exception/destination_encoding_spec.rb index c3ad0342a1..5709c31e55 100644 --- a/spec/ruby/core/exception/destination_encoding_spec.rb +++ b/spec/ruby/core/exception/destination_encoding_spec.rb @@ -1,9 +1,23 @@ require_relative '../../spec_helper' describe "Encoding::UndefinedConversionError#destination_encoding" do - it "needs to be reviewed for spec completeness" + it "returns the destination encoding" do + ec = Encoding::Converter.new("ISO-8859-1", "EUC-JP") + begin + ec.convert("\xa0") + rescue Encoding::UndefinedConversionError => e + e.destination_encoding.should == Encoding::EUC_JP + end + end end describe "Encoding::InvalidByteSequenceError#destination_encoding" do - it "needs to be reviewed for spec completeness" + it "returns the destination encoding" do + ec = Encoding::Converter.new("EUC-JP", "ISO-8859-1") + begin + ec.convert("\xa0") + rescue Encoding::InvalidByteSequenceError => e + e.destination_encoding.should == Encoding::UTF_8 + end + end end diff --git a/spec/ruby/core/exception/error_bytes_spec.rb b/spec/ruby/core/exception/error_bytes_spec.rb index 2a95bcfdf4..66dd4b62c1 100644 --- a/spec/ruby/core/exception/error_bytes_spec.rb +++ b/spec/ruby/core/exception/error_bytes_spec.rb @@ -1,5 +1,12 @@ require_relative '../../spec_helper' describe "Encoding::InvalidByteSequenceError#error_bytes" do - it "needs to be reviewed for spec completeness" + it "returns the error bytes" do + ec = Encoding::Converter.new("EUC-JP", "ISO-8859-1") + begin + ec.convert("\xa0") + rescue Encoding::InvalidByteSequenceError => e + e.error_bytes.should == "\xA0".force_encoding("ASCII-8BIT") + end + end end diff --git a/spec/ruby/core/exception/error_char_spec.rb b/spec/ruby/core/exception/error_char_spec.rb index c0256af03a..f95ae2a6ce 100644 --- a/spec/ruby/core/exception/error_char_spec.rb +++ b/spec/ruby/core/exception/error_char_spec.rb @@ -1,5 +1,12 @@ require_relative '../../spec_helper' describe "Encoding::UndefinedConversionError#error_char" do - it "needs to be reviewed for spec completeness" + it "returns the error char" do + ec = Encoding::Converter.new("ISO-8859-1", "EUC-JP") + begin + ec.convert("\xa0") + rescue Encoding::UndefinedConversionError => e + e.error_char.should == "\u00A0" + end + end end diff --git a/spec/ruby/core/exception/exception_spec.rb b/spec/ruby/core/exception/exception_spec.rb index 3a01366920..d6f5283bd9 100644 --- a/spec/ruby/core/exception/exception_spec.rb +++ b/spec/ruby/core/exception/exception_spec.rb @@ -6,48 +6,6 @@ describe "Exception.exception" do it_behaves_like :exception_new, :exception end -describe "Exception" do - it "is a Class" do - Exception.should be_kind_of(Class) - end - - it "is a superclass of NoMemoryError" do - Exception.should be_ancestor_of(NoMemoryError) - end - - it "is a superclass of ScriptError" do - Exception.should be_ancestor_of(ScriptError) - end - - it "is a superclass of SignalException" do - Exception.should be_ancestor_of(SignalException) - end - - it "is a superclass of Interrupt" do - SignalException.should be_ancestor_of(Interrupt) - end - - it "is a superclass of StandardError" do - Exception.should be_ancestor_of(StandardError) - end - - it "is a superclass of SystemExit" do - Exception.should be_ancestor_of(SystemExit) - end - - it "is a superclass of SystemStackError" do - Exception.should be_ancestor_of(SystemStackError) - end - - it "is a superclass of SecurityError" do - Exception.should be_ancestor_of(SecurityError) - end - - it "is a superclass of EncodingError" do - Exception.should be_ancestor_of(EncodingError) - end -end - describe "Exception#exception" do it "returns self when passed no argument" do e = RuntimeError.new @@ -82,6 +40,18 @@ describe "Exception#exception" do raised_second.should == caught_second end + it "captures an exception into $!" do + exception = begin + raise + rescue RuntimeError + $! + end + + exception.class.should == RuntimeError + exception.message.should == "" + exception.backtrace.first.should =~ /exception_spec/ + end + class CustomArgumentError < StandardError attr_reader :val def initialize(val) diff --git a/spec/ruby/core/exception/hierarchy_spec.rb b/spec/ruby/core/exception/hierarchy_spec.rb new file mode 100644 index 0000000000..e52811c761 --- /dev/null +++ b/spec/ruby/core/exception/hierarchy_spec.rb @@ -0,0 +1,62 @@ +require_relative '../../spec_helper' + +describe "Exception" do + it "has the right class hierarchy" do + hierarchy = { + Exception => { + NoMemoryError => nil, + ScriptError => { + LoadError => nil, + NotImplementedError => nil, + SyntaxError => nil, + }, + SecurityError => nil, + SignalException => { + Interrupt => nil, + }, + StandardError => { + ArgumentError => { + UncaughtThrowError => nil, + }, + EncodingError => nil, + FiberError => nil, + IOError => { + EOFError => nil, + }, + IndexError => { + KeyError => nil, + StopIteration => { + ClosedQueueError => nil, + }, + }, + LocalJumpError => nil, + NameError => { + NoMethodError => nil, + }, + RangeError => { + FloatDomainError => nil, + }, + RegexpError => nil, + RuntimeError => nil, + SystemCallError => nil, + ThreadError => nil, + TypeError => nil, + ZeroDivisionError => nil, + }, + SystemExit => nil, + SystemStackError => nil, + }, + } + ruby_version_is "2.5" do + hierarchy[Exception][StandardError][RuntimeError] = {FrozenError => nil} + end + traverse = -> parent_class, parent_subclass_hash { + parent_subclass_hash.each do |child_class, child_subclass_hash| + child_class.class.should == Class + child_class.superclass.should == parent_class + traverse.call(child_class, child_subclass_hash) if child_subclass_hash + end + } + traverse.call(Object, hierarchy) + end +end diff --git a/spec/ruby/core/exception/interrupt_spec.rb b/spec/ruby/core/exception/interrupt_spec.rb index bc01b7b703..14f294bec6 100644 --- a/spec/ruby/core/exception/interrupt_spec.rb +++ b/spec/ruby/core/exception/interrupt_spec.rb @@ -1,11 +1,5 @@ require_relative '../../spec_helper' -describe "Interrupt" do - it "is a subclass of SignalException" do - Interrupt.superclass.should == SignalException - end -end - describe "Interrupt.new" do it "returns an instance of interrupt with no message given" do e = Interrupt.new diff --git a/spec/ruby/core/exception/readagain_bytes_spec.rb b/spec/ruby/core/exception/readagain_bytes_spec.rb index f7e8d9d1d3..0f1e24f1cf 100644 --- a/spec/ruby/core/exception/readagain_bytes_spec.rb +++ b/spec/ruby/core/exception/readagain_bytes_spec.rb @@ -1,5 +1,12 @@ require_relative '../../spec_helper' describe "Encoding::InvalidByteSequenceError#readagain_bytes" do - it "needs to be reviewed for spec completeness" + it "returns the next byte" do + begin + "abc\xa4def".encode("ISO-8859-1", "EUC-JP") + rescue Encoding::InvalidByteSequenceError => e + e.error_bytes.should == "\xA4".force_encoding("ASCII-8BIT") + e.readagain_bytes.should == 'd' + end + end end diff --git a/spec/ruby/core/exception/script_error_spec.rb b/spec/ruby/core/exception/script_error_spec.rb deleted file mode 100644 index e33a5d3a58..0000000000 --- a/spec/ruby/core/exception/script_error_spec.rb +++ /dev/null @@ -1,15 +0,0 @@ -require_relative '../../spec_helper' - -describe "ScriptError" do - it "is a superclass of LoadError" do - ScriptError.should be_ancestor_of(LoadError) - end - - it "is a superclass of NotImplementedError" do - ScriptError.should be_ancestor_of(NotImplementedError) - end - - it "is a superclass of SyntaxError" do - ScriptError.should be_ancestor_of(SyntaxError) - end -end diff --git a/spec/ruby/core/exception/signal_exception_spec.rb b/spec/ruby/core/exception/signal_exception_spec.rb index e0b30236f7..e494e18cde 100644 --- a/spec/ruby/core/exception/signal_exception_spec.rb +++ b/spec/ruby/core/exception/signal_exception_spec.rb @@ -30,6 +30,12 @@ describe "SignalException.new" do -> { SignalException.new("NONEXISTENT") }.should raise_error(ArgumentError) end + ruby_version_is "2.6" do + it "raises an exception with an invalid first argument type" do + -> { SignalException.new(Object.new) }.should raise_error(ArgumentError) + end + end + it "takes a signal symbol without SIG prefix as the first argument" do exc = SignalException.new(:INT) exc.signo.should == Signal.list["INT"] @@ -72,3 +78,48 @@ describe "rescuing SignalException" do end end end + +describe "SignalException" do + it "can be rescued" do + ruby_exe(<<-RUBY) + begin + raise SignalException, 'SIGKILL' + rescue SignalException + exit(0) + end + exit(1) + RUBY + + $?.exitstatus.should == 0 + end + + platform_is_not :windows do + it "runs after at_exit" do + output = ruby_exe(<<-RUBY) + at_exit do + puts "hello" + $stdout.flush + end + + raise SignalException, 'SIGKILL' + RUBY + + $?.termsig.should == Signal.list.fetch("KILL") + output.should == "hello\n" + end + + it "cannot be trapped with Signal.trap" do + ruby_exe(<<-RUBY) + Signal.trap("PROF") {} + raise(SignalException, "PROF") + RUBY + + $?.termsig.should == Signal.list.fetch("PROF") + end + + it "self-signals for USR1" do + ruby_exe("raise(SignalException, 'USR1')") + $?.termsig.should == Signal.list.fetch('USR1') + end + end +end diff --git a/spec/ruby/core/exception/source_encoding_name_spec.rb b/spec/ruby/core/exception/source_encoding_name_spec.rb index bd8bc359b6..6f5dbd01aa 100644 --- a/spec/ruby/core/exception/source_encoding_name_spec.rb +++ b/spec/ruby/core/exception/source_encoding_name_spec.rb @@ -1,9 +1,23 @@ require_relative '../../spec_helper' describe "Encoding::UndefinedConversionError#source_encoding_name" do - it "needs to be reviewed for spec completeness" + it "returns the source encoding name" do + ec = Encoding::Converter.new("ISO-8859-1", "EUC-JP") + begin + ec.convert("\xa0") + rescue Encoding::UndefinedConversionError => e + e.source_encoding_name.should == "UTF-8" + end + end end describe "Encoding::InvalidByteSequenceError#source_encoding_name" do - it "needs to be reviewed for spec completeness" + it "returns the source encoding name" do + ec = Encoding::Converter.new("EUC-JP", "ISO-8859-1") + begin + ec.convert("\xa0") + rescue Encoding::InvalidByteSequenceError => e + e.source_encoding_name.should == "EUC-JP" + end + end end diff --git a/spec/ruby/core/exception/source_encoding_spec.rb b/spec/ruby/core/exception/source_encoding_spec.rb index 65ac98d791..fac38e75f4 100644 --- a/spec/ruby/core/exception/source_encoding_spec.rb +++ b/spec/ruby/core/exception/source_encoding_spec.rb @@ -1,9 +1,23 @@ require_relative '../../spec_helper' describe "Encoding::UndefinedConversionError#source_encoding" do - it "needs to be reviewed for spec completeness" + it "returns the source encoding" do + ec = Encoding::Converter.new("ISO-8859-1", "EUC-JP") + begin + ec.convert("\xa0") + rescue Encoding::UndefinedConversionError => e + e.source_encoding.should == Encoding::UTF_8 + end + end end describe "Encoding::InvalidByteSequenceError#source_encoding" do - it "needs to be reviewed for spec completeness" + it "returns the source encoding" do + ec = Encoding::Converter.new("EUC-JP", "ISO-8859-1") + begin + ec.convert("\xa0") + rescue Encoding::InvalidByteSequenceError => e + e.source_encoding.should == Encoding::EUC_JP + end + end end diff --git a/spec/ruby/core/exception/standard_error_spec.rb b/spec/ruby/core/exception/standard_error_spec.rb index 1b469b5090..17e98ce7f0 100644 --- a/spec/ruby/core/exception/standard_error_spec.rb +++ b/spec/ruby/core/exception/standard_error_spec.rb @@ -1,56 +1,23 @@ require_relative '../../spec_helper' describe "StandardError" do - it "is a superclass of ArgumentError" do - StandardError.should be_ancestor_of(ArgumentError) - end - - it "is a superclass of IOError" do - StandardError.should be_ancestor_of(IOError) - end - - it "is a superclass of IndexError" do - StandardError.should be_ancestor_of(IndexError) - end - - it "is a superclass of LocalJumpError" do - StandardError.should be_ancestor_of(LocalJumpError) - end - - it "is a superclass of NameError" do - StandardError.should be_ancestor_of(NameError) - end - - it "is a superclass of RangeError" do - StandardError.should be_ancestor_of(RangeError) - end - - it "is a superclass of RegexpError" do - StandardError.should be_ancestor_of(RegexpError) - end - - it "is a superclass of RuntimeError" do - StandardError.should be_ancestor_of(RuntimeError) - end - - it "is a superclass of SystemCallError" do - StandardError.should be_ancestor_of(SystemCallError.new("").class) - end - it "is a superclass of ThreadError" do - StandardError.should be_ancestor_of(ThreadError) - end - - it "is a superclass of TypeError" do - StandardError.should be_ancestor_of(TypeError) + it "rescues StandardError" do + begin + raise StandardError + rescue => exception + exception.class.should == StandardError + end end - it "is a superclass of ZeroDivisionError" do - StandardError.should be_ancestor_of(ZeroDivisionError) + it "rescues subclass of StandardError" do + begin + raise RuntimeError + rescue => exception + exception.class.should == RuntimeError + end end - ruby_version_is '2.5' do - it "is a superclass of FrozenError" do - StandardError.should be_ancestor_of(FrozenError) - end + it "does not rescue superclass of StandardError" do + -> { begin; raise Exception; rescue; end }.should raise_error(Exception) end end diff --git a/spec/ruby/core/exception/system_call_error_spec.rb b/spec/ruby/core/exception/system_call_error_spec.rb index c07c8af72c..c510ae440f 100644 --- a/spec/ruby/core/exception/system_call_error_spec.rb +++ b/spec/ruby/core/exception/system_call_error_spec.rb @@ -20,41 +20,82 @@ describe "SystemCallError" do end describe "SystemCallError.new" do + before :all do + @example_errno = Errno::EINVAL::Errno + @example_errno_class = Errno::EINVAL + @last_known_errno = Errno.constants.size - 1 + @unknown_errno = Errno.constants.size + end + it "requires at least one argument" do -> { SystemCallError.new }.should raise_error(ArgumentError) end it "accepts single Fixnum argument as errno" do SystemCallError.new(-2**24).errno.should == -2**24 - SystemCallError.new(42).errno.should == 42 + SystemCallError.new(-1).errno.should == -1 + SystemCallError.new(0).errno.should == 0 + SystemCallError.new(@last_known_errno).errno.should == @last_known_errno + SystemCallError.new(@unknown_errno).errno.should == @unknown_errno SystemCallError.new(2**24).errno.should == 2**24 end + it "constructs a SystemCallError for an unknown error number" do + SystemCallError.new(-2**24).should be_an_instance_of(SystemCallError) + SystemCallError.new(-1).should be_an_instance_of(SystemCallError) + SystemCallError.new(@unknown_errno).should be_an_instance_of(SystemCallError) + SystemCallError.new(2**24).should be_an_instance_of(SystemCallError) + end + it "constructs the appropriate Errno class" do - # EINVAL should be more or less mortable across the platforms, - # so let's use it then. - SystemCallError.new(22).should be_kind_of(SystemCallError) - SystemCallError.new(22).should be_an_instance_of(Errno::EINVAL) - SystemCallError.new(2**28).should be_an_instance_of(SystemCallError) + e = SystemCallError.new(@example_errno) + e.should be_kind_of(SystemCallError) + e.should be_an_instance_of(@example_errno_class) end it "accepts an optional custom message preceding the errno" do - exc = SystemCallError.new("custom message", 22) - exc.should be_an_instance_of(Errno::EINVAL) - exc.errno.should == 22 - exc.message.should == "Invalid argument - custom message" + exc = SystemCallError.new("custom message", @example_errno) + exc.should be_an_instance_of(@example_errno_class) + exc.errno.should == @example_errno + exc.message.should == 'Invalid argument - custom message' end it "accepts an optional third argument specifying the location" do - exc = SystemCallError.new("custom message", 22, "location") - exc.should be_an_instance_of(Errno::EINVAL) - exc.errno.should == 22 - exc.message.should == "Invalid argument @ location - custom message" + exc = SystemCallError.new("custom message", @example_errno, "location") + exc.should be_an_instance_of(@example_errno_class) + exc.errno.should == @example_errno + exc.message.should == 'Invalid argument @ location - custom message' + end + + it "coerces location if it is not a String" do + e = SystemCallError.new('foo', 1, :not_a_string) + e.message.should =~ /@ not_a_string - foo/ end it "returns an arity of -1 for the initialize method" do SystemCallError.instance_method(:initialize).arity.should == -1 end + + it "converts to Integer if errno is a Float" do + SystemCallError.new('foo', 2.0).should == SystemCallError.new('foo', 2) + SystemCallError.new('foo', 2.9).should == SystemCallError.new('foo', 2) + end + + it "converts to Integer if errno is a Complex convertible to Integer" do + SystemCallError.new('foo', Complex(2.9, 0)).should == SystemCallError.new('foo', 2) + end + + it "raises TypeError if message is not a String" do + -> { SystemCallError.new(:foo, 1) }.should raise_error(TypeError, /no implicit conversion of Symbol into String/) + end + + it "raises TypeError if errno is not an Integer" do + -> { SystemCallError.new('foo', 'bar') }.should raise_error(TypeError, /no implicit conversion of String into Integer/) + end + + it "raises RangeError if errno is a Complex not convertible to Integer" do + -> { SystemCallError.new('foo', Complex(2.9, 1)) }.should raise_error(RangeError, /can't convert/) + end end describe "SystemCallError#errno" do diff --git a/spec/ruby/core/exception/to_s_spec.rb b/spec/ruby/core/exception/to_s_spec.rb index 8570b18cfd..4c4c7ab432 100644 --- a/spec/ruby/core/exception/to_s_spec.rb +++ b/spec/ruby/core/exception/to_s_spec.rb @@ -19,5 +19,19 @@ describe "Exception#to_s" do end describe "NameError#to_s" do - it "needs to be reviewed for spec completeness" + it "raises its own message for an undefined variable" do + begin + puts not_defined + rescue => exception + exception.message.should =~ /undefined local variable or method `not_defined'/ + end + end + + it "raises its own message for an undefined constant" do + begin + puts NotDefined + rescue => exception + exception.message.should =~ /uninitialized constant NotDefined/ + end + end end diff --git a/spec/ruby/core/file/ftype_spec.rb b/spec/ruby/core/file/ftype_spec.rb index 20e9af7e5f..8ff70baa80 100644 --- a/spec/ruby/core/file/ftype_spec.rb +++ b/spec/ruby/core/file/ftype_spec.rb @@ -12,8 +12,9 @@ describe "File.ftype" do end it "raises Errno::ENOENT if the file is not valid" do - l = -> { File.ftype("/#{$$}#{Time.now.to_f}") } - l.should raise_error(Errno::ENOENT) + -> { + File.ftype("/#{$$}#{Time.now.to_f}") + }.should raise_error(Errno::ENOENT) end it "returns a String" do diff --git a/spec/ruby/core/file/lutime_spec.rb b/spec/ruby/core/file/lutime_spec.rb new file mode 100644 index 0000000000..7449bc4389 --- /dev/null +++ b/spec/ruby/core/file/lutime_spec.rb @@ -0,0 +1,40 @@ +require_relative '../../spec_helper' + +ruby_version_is "2.5" do + describe "File.lutime" do + platform_is_not :windows do + before :each do + @atime = Time.utc(2000) + @mtime = Time.utc(2001) + @file = tmp("specs_lutime_file") + @symlink = tmp("specs_lutime_symlink") + touch @file + File.symlink(@file, @symlink) + end + + after :each do + rm_r @file, @symlink + end + + it "sets the access and modification time for a regular file" do + File.lutime(@atime, @mtime, @file) + stat = File.stat(@file) + stat.atime.should == @atime + stat.mtime.should === @mtime + end + + it "sets the access and modification time for a symlink" do + original = File.stat(@file) + + File.lutime(@atime, @mtime, @symlink) + stat = File.lstat(@symlink) + stat.atime.should == @atime + stat.mtime.should === @mtime + + file = File.stat(@file) + file.atime.should == original.atime + file.mtime.should == original.mtime + end + end + end +end diff --git a/spec/ruby/core/file/open_spec.rb b/spec/ruby/core/file/open_spec.rb index 93f1972ac6..e3c5618795 100644 --- a/spec/ruby/core/file/open_spec.rb +++ b/spec/ruby/core/file/open_spec.rb @@ -623,6 +623,14 @@ describe "File.open" do end end + ruby_version_is "2.5" do + it "raises ArgumentError if mixing :newline and binary mode" do + -> { + File.open(@file, "rb", newline: :universal) {} + }.should raise_error(ArgumentError, "newline decorator with binary mode") + end + end + ruby_version_is "2.6" do context "'x' flag" do before :each do diff --git a/spec/ruby/core/float/comparison_spec.rb b/spec/ruby/core/float/comparison_spec.rb index 4205d95c83..2dc993a176 100644 --- a/spec/ruby/core/float/comparison_spec.rb +++ b/spec/ruby/core/float/comparison_spec.rb @@ -16,6 +16,38 @@ describe "Float#<=>" do (1.0 <=> "1").should be_nil end + it "compares using #coerce when argument is not a Float" do + klass = Class.new do + attr_reader :call_count + def coerce(other) + @call_count ||= 0 + @call_count += 1 + [other, 42.0] + end + end + + coercible = klass.new + (2.33 <=> coercible).should == -1 + (42.0 <=> coercible).should == 0 + (43.0 <=> coercible).should == 1 + coercible.call_count.should == 3 + end + + ruby_version_is "2.5" do + it "raises TypeError when #coerce misbehaves" do + klass = Class.new do + def coerce(other) + :incorrect + end + end + + bad_coercible = klass.new + -> { + 4.2 <=> bad_coercible + }.should raise_error(TypeError, "coerce must return [x, y]") + end + end + # The 4 tests below are taken from matz's revision 23730 for Ruby trunk # it "returns 1 when self is Infinity and other is a Bignum" do diff --git a/spec/ruby/core/integer/constants_spec.rb b/spec/ruby/core/integer/constants_spec.rb new file mode 100644 index 0000000000..3b8b01e330 --- /dev/null +++ b/spec/ruby/core/integer/constants_spec.rb @@ -0,0 +1,25 @@ +require_relative '../../spec_helper' + +describe "Fixnum" do + it "is unified into Integer" do + suppress_warning do + Fixnum.should equal(Integer) + end + end + + it "is deprecated" do + -> { Fixnum }.should complain(/constant ::Fixnum is deprecated/) + end +end + +describe "Bignum" do + it "is unified into Integer" do + suppress_warning do + Bignum.should equal(Integer) + end + end + + it "is deprecated" do + -> { Bignum }.should complain(/constant ::Bignum is deprecated/) + end +end diff --git a/spec/ruby/core/io/popen_spec.rb b/spec/ruby/core/io/popen_spec.rb index 622b3a9394..4f873e61cd 100644 --- a/spec/ruby/core/io/popen_spec.rb +++ b/spec/ruby/core/io/popen_spec.rb @@ -1,13 +1,22 @@ require_relative '../../spec_helper' require_relative 'fixtures/classes' +require_relative '../process/fixtures/common' describe "IO.popen" do + ProcessSpecs.use_system_ruby(self) + before :each do + @fname = tmp("IO_popen_spec") @io = nil + @var = "$FOO" + platform_is :windows do + @var = "%FOO%" + end end after :each do - @io.close if @io + @io.close if @io and !@io.closed? + rm_r @fname end it "returns an open IO" do @@ -16,27 +25,15 @@ describe "IO.popen" do end it "reads a read-only pipe" do - @io = IO.popen(ruby_cmd('puts "foo"'), "r") + @io = IO.popen('echo foo', "r") @io.read.should == "foo\n" end it "raises IOError when writing a read-only pipe" do - @io = IO.popen(ruby_cmd('puts "foo"'), "r") + @io = IO.popen('echo foo', "r") -> { @io.write('bar') }.should raise_error(IOError) @io.read.should == "foo\n" end -end - -describe "IO.popen" do - before :each do - @fname = tmp("IO_popen_spec") - @io = nil - end - - after :each do - @io.close if @io and !@io.closed? - rm_r @fname - end it "sees an infinitely looping subprocess exit when read pipe is closed" do io = IO.popen ruby_cmd('r = loop{puts "y"; 0} rescue 1; exit r'), 'r' @@ -97,16 +94,6 @@ describe "IO.popen" do mode.should_receive(:to_str).and_return("r") @io = IO.popen(ruby_cmd('exit 0'), mode) end -end - -describe "IO.popen" do - before :each do - @io = nil - end - - after :each do - @io.close if @io - end describe "with a block" do it "yields an open IO to the block" do @@ -171,13 +158,13 @@ describe "IO.popen" do context "with a leading ENV Hash" do it "accepts a single String command" do - IO.popen({"FOO" => "bar"}, ruby_cmd('puts ENV["FOO"]')) do |io| + IO.popen({"FOO" => "bar"}, "echo #{@var}") do |io| io.read.should == "bar\n" end end it "accepts a single String command, and an IO mode" do - IO.popen({"FOO" => "bar"}, ruby_cmd('puts ENV["FOO"]'), "r") do |io| + IO.popen({"FOO" => "bar"}, "echo #{@var}", "r") do |io| io.read.should == "bar\n" end end diff --git a/spec/ruby/core/kernel/rand_spec.rb b/spec/ruby/core/kernel/rand_spec.rb index 843b5d10a2..a82b4fba74 100644 --- a/spec/ruby/core/kernel/rand_spec.rb +++ b/spec/ruby/core/kernel/rand_spec.rb @@ -138,6 +138,16 @@ describe "Kernel.rand" do rand(KernelSpecs::CustomRangeFloat.new(1.0)..KernelSpecs::CustomRangeFloat.new(42.0)).should be_an_instance_of(KernelSpecs::CustomRangeFloat) rand(Time.now..Time.now).should be_an_instance_of(Time) end + + it "is random on boot" do + results = 2.times.map { + out = ruby_exe('p rand', options: '--disable-gems') + Float(out) + } + results.size.should == 2 + # this is technically flaky, but very unlikely in a good distribution + results[0].should_not == results[1] + end end describe "Kernel#rand" do diff --git a/spec/ruby/core/kernel/shared/load.rb b/spec/ruby/core/kernel/shared/load.rb index 14bf5f27da..120619abef 100644 --- a/spec/ruby/core/kernel/shared/load.rb +++ b/spec/ruby/core/kernel/shared/load.rb @@ -1,3 +1,5 @@ +main = self + describe :kernel_load, shared: true do before :each do CodeLoadingSpecs.spec_setup @@ -95,13 +97,45 @@ describe :kernel_load, shared: true do @object.load(path, true) Object.const_defined?(:LoadSpecWrap).should be_false + + wrap_module = ScratchPad.recorded[1] + wrap_module.should be_an_instance_of(Module) end it "allows referencing outside namespaces" do path = File.expand_path "wrap_fixture.rb", CODE_LOADING_DIR @object.load(path, true) - ScratchPad.recorded.first.should be_an_instance_of(Class) + ScratchPad.recorded[0].should equal(String) + end + + it "sets self as a copy of the top-level main" do + path = File.expand_path "wrap_fixture.rb", CODE_LOADING_DIR + @object.load(path, true) + + top_level = ScratchPad.recorded[2] + top_level.to_s.should == "main" + top_level.method(:to_s).owner.should == top_level.singleton_class + top_level.should_not equal(main) + top_level.should be_an_instance_of(Object) + end + + it "includes modules included in main's singleton class in self's class" do + mod = Module.new + main.extend(mod) + + main_ancestors = main.singleton_class.ancestors[1..-1] + main_ancestors.first.should == mod + + path = File.expand_path "wrap_fixture.rb", CODE_LOADING_DIR + @object.load(path, true) + + top_level = ScratchPad.recorded[2] + top_level_ancestors = top_level.singleton_class.ancestors[-main_ancestors.size..-1] + top_level_ancestors.should == main_ancestors + + wrap_module = ScratchPad.recorded[1] + top_level.singleton_class.ancestors.should == [top_level.singleton_class, wrap_module, *main_ancestors] end describe "with top-level methods" do diff --git a/spec/ruby/core/marshal/dump_spec.rb b/spec/ruby/core/marshal/dump_spec.rb index 3a7a083dd8..fc78ca4ff9 100644 --- a/spec/ruby/core/marshal/dump_spec.rb +++ b/spec/ruby/core/marshal/dump_spec.rb @@ -473,6 +473,12 @@ describe "Marshal.dump" do Marshal.dump(obj).should == "\x04\bo:\x0EException\a:\tmesg\"\bfoo:\abt[\x06\"\x12foo/bar.rb:10" end + it "dumps instance variables if they exist" do + obj = Exception.new("foo") + obj.instance_variable_set(:@ivar, 1) + Marshal.dump(obj).should == "\x04\bo:\x0EException\b:\tmesg\"\bfoo:\abt0:\n@ivari\x06" + end + it "dumps the cause for the exception" do exc = nil begin diff --git a/spec/ruby/core/marshal/shared/load.rb b/spec/ruby/core/marshal/shared/load.rb index b90a6a99ce..302d3d5bda 100644 --- a/spec/ruby/core/marshal/shared/load.rb +++ b/spec/ruby/core/marshal/shared/load.rb @@ -531,6 +531,19 @@ describe :marshal_load, shared: true do loaded.message.should == obj.message loaded.backtrace.should == obj.backtrace end + + it "loads an marshalled exception with ivars" do + s = 'hi' + arr = [:so, :so, s, s] + obj = Exception.new("foo") + obj.instance_variable_set :@arr, arr + + loaded = Marshal.send(@method, "\x04\bo:\x0EException\b:\tmesg\"\bfoo:\abt0:\t@arr[\t:\aso;\t\"\ahi@\b") + new_arr = loaded.instance_variable_get :@arr + + loaded.message.should == obj.message + new_arr.should == arr + end end describe "for an Object" do diff --git a/spec/ruby/core/matchdata/allocate_spec.rb b/spec/ruby/core/matchdata/allocate_spec.rb new file mode 100644 index 0000000000..9f3ada4018 --- /dev/null +++ b/spec/ruby/core/matchdata/allocate_spec.rb @@ -0,0 +1,10 @@ +require_relative '../../spec_helper' + +describe "MatchData.allocate" do + ruby_version_is "2.7" do + it "is undefined" do + # https://bugs.ruby-lang.org/issues/16294 + -> { MatchData.allocate }.should raise_error(NoMethodError) + end + end +end diff --git a/spec/ruby/core/matchdata/dup_spec.rb b/spec/ruby/core/matchdata/dup_spec.rb new file mode 100644 index 0000000000..70877f07eb --- /dev/null +++ b/spec/ruby/core/matchdata/dup_spec.rb @@ -0,0 +1,14 @@ +require_relative '../../spec_helper' + +describe "MatchData#dup" do + it "duplicates the match data" do + original = /ll/.match("hello") + original.instance_variable_set(:@custom_ivar, 42) + duplicate = original.dup + + duplicate.instance_variable_get(:@custom_ivar).should == 42 + original.regexp.should == duplicate.regexp + original.string.should == duplicate.string + original.offset(0).should == duplicate.offset(0) + end +end diff --git a/spec/ruby/core/matchdata/regexp_spec.rb b/spec/ruby/core/matchdata/regexp_spec.rb index 7a4783434c..099b59c559 100644 --- a/spec/ruby/core/matchdata/regexp_spec.rb +++ b/spec/ruby/core/matchdata/regexp_spec.rb @@ -11,6 +11,12 @@ describe "MatchData#regexp" do m.regexp.should == /hay/ end + it "returns the same Regexp used to match" do + r = /hay/ + m = 'haystack'.match(r) + m.regexp.object_id.should == r.object_id + end + it "returns a Regexp for the result of gsub(String)" do 'he[[o'.gsub('[', ']') $~.regexp.should == /\[/ diff --git a/spec/ruby/core/module/autoload_spec.rb b/spec/ruby/core/module/autoload_spec.rb index df434e8e60..db95704cc7 100644 --- a/spec/ruby/core/module/autoload_spec.rb +++ b/spec/ruby/core/module/autoload_spec.rb @@ -652,6 +652,27 @@ describe "Module#autoload" do ModuleSpecs::Autoload::AutoloadDuringRequire.should be_kind_of(Class) end + it "does not call #require a second time and does not warn if feature sets and trigger autoload on itself" do + main = TOPLEVEL_BINDING.eval("self") + main.should_not_receive(:require) + + -> { + Kernel.require fixture(__FILE__, "autoload_self_during_require.rb") + }.should_not complain(verbose: true) + ModuleSpecs::Autoload::AutoloadSelfDuringRequire.should be_kind_of(Class) + end + + it "handles multiple autoloads in the same file" do + $LOAD_PATH.unshift(File.expand_path('../fixtures/multi', __FILE__)) + begin + require 'foo/bar_baz' + ModuleSpecs::Autoload::Foo::Bar.should be_kind_of(Class) + ModuleSpecs::Autoload::Foo::Baz.should be_kind_of(Class) + ensure + $LOAD_PATH.shift + end + end + it "calls #to_path on non-string filenames" do p = mock('path') p.should_receive(:to_path).and_return @non_existent diff --git a/spec/ruby/core/module/fixtures/autoload_self_during_require.rb b/spec/ruby/core/module/fixtures/autoload_self_during_require.rb new file mode 100644 index 0000000000..f4a514a807 --- /dev/null +++ b/spec/ruby/core/module/fixtures/autoload_self_during_require.rb @@ -0,0 +1,5 @@ +module ModuleSpecs::Autoload + autoload :AutoloadSelfDuringRequire, __FILE__ + class AutoloadSelfDuringRequire + end +end diff --git a/spec/ruby/core/module/fixtures/classes.rb b/spec/ruby/core/module/fixtures/classes.rb index ef70eaf9cf..40777cdbbd 100644 --- a/spec/ruby/core/module/fixtures/classes.rb +++ b/spec/ruby/core/module/fixtures/classes.rb @@ -6,6 +6,9 @@ module ModuleSpecs CONST = :plain_constant + class NamedClass + end + module PrivConstModule PRIVATE_CONSTANT = 1 private_constant :PRIVATE_CONSTANT diff --git a/spec/ruby/core/module/fixtures/multi/foo.rb b/spec/ruby/core/module/fixtures/multi/foo.rb new file mode 100644 index 0000000000..549996f08f --- /dev/null +++ b/spec/ruby/core/module/fixtures/multi/foo.rb @@ -0,0 +1,6 @@ +module ModuleSpecs::Autoload + module Foo + autoload :Bar, 'foo/bar_baz' + autoload :Baz, 'foo/bar_baz' + end +end diff --git a/spec/ruby/core/module/fixtures/multi/foo/bar_baz.rb b/spec/ruby/core/module/fixtures/multi/foo/bar_baz.rb new file mode 100644 index 0000000000..53d3849e1f --- /dev/null +++ b/spec/ruby/core/module/fixtures/multi/foo/bar_baz.rb @@ -0,0 +1,11 @@ +require 'foo' + +module ModuleSpecs::Autoload + module Foo + class Bar + end + + class Baz + end + end +end diff --git a/spec/ruby/core/module/shared/set_visibility.rb b/spec/ruby/core/module/shared/set_visibility.rb index c39d59e05d..a04b1a54a0 100644 --- a/spec/ruby/core/module/shared/set_visibility.rb +++ b/spec/ruby/core/module/shared/set_visibility.rb @@ -5,6 +5,23 @@ describe :set_visibility, shared: true do Module.should have_private_instance_method(@method, false) end + describe "with argument" do + it "does not clone method from the ancestor when setting to the same visibility in a child" do + visibility = @method + parent = Module.new { + def test_method; end + send(visibility, :test_method) + } + + child = Module.new { + include parent + send(visibility, :test_method) + } + + child.should_not send(:"have_#{visibility}_instance_method", :test_method, false) + end + end + describe "without arguments" do it "sets visibility to following method definitions" do visibility = @method diff --git a/spec/ruby/core/module/to_s_spec.rb b/spec/ruby/core/module/to_s_spec.rb index bebdcf6e1b..29f6ecf726 100644 --- a/spec/ruby/core/module/to_s_spec.rb +++ b/spec/ruby/core/module/to_s_spec.rb @@ -2,17 +2,44 @@ require_relative '../../spec_helper' require_relative 'fixtures/classes' describe "Module#to_s" do + it 'returns the name of the module if it has a name' do + Enumerable.to_s.should == 'Enumerable' + String.to_s.should == 'String' + end + it "returns the full constant path leading to the module" do ModuleSpecs::LookupMod.to_s.should == "ModuleSpecs::LookupMod" end it "works with an anonymous module" do m = Module.new - m.to_s.should =~ /#/ + m.to_s.should =~ /\A#\z/ end it "works with an anonymous class" do c = Class.new - c.to_s.should =~ /#/ + c.to_s.should =~ /\A#\z/ + end + + it 'for the singleton class of an object of an anonymous class' do + klass = Class.new + obj = klass.new + sclass = obj.singleton_class + sclass.to_s.should == "#" + sclass.to_s.should =~ /\A#>\z/ + sclass.to_s.should =~ /\A#:0x\h+>>\z/ + end + + it 'for a singleton class of a module includes the module name' do + ModuleSpecs.singleton_class.to_s.should == '#' + end + + it 'for a metaclass includes the class name' do + ModuleSpecs::NamedClass.singleton_class.to_s.should == '#' + end + + it 'for objects includes class name and object ID' do + obj = ModuleSpecs::NamedClass.new + obj.singleton_class.to_s.should =~ /\A#>\z/ end end diff --git a/spec/ruby/core/module/undef_method_spec.rb b/spec/ruby/core/module/undef_method_spec.rb index 9b2c9240f4..b101778962 100644 --- a/spec/ruby/core/module/undef_method_spec.rb +++ b/spec/ruby/core/module/undef_method_spec.rb @@ -56,8 +56,37 @@ describe "Module#undef_method" do @module.send(:undef_method, :method_to_undef).should equal(@module) end - it "raises a NameError when passed a missing name" do - -> { @module.send :undef_method, :not_exist }.should raise_error(NameError) { |e| + it "raises a NameError when passed a missing name for a module" do + -> { @module.send :undef_method, :not_exist }.should raise_error(NameError, /undefined method `not_exist' for module `#{@module}'/) { |e| + # a NameError and not a NoMethodError + e.class.should == NameError + } + end + + it "raises a NameError when passed a missing name for a class" do + klass = Class.new + -> { klass.send :undef_method, :not_exist }.should raise_error(NameError, /undefined method `not_exist' for class `#{klass}'/) { |e| + # a NameError and not a NoMethodError + e.class.should == NameError + } + end + + it "raises a NameError when passed a missing name for a singleton class" do + klass = Class.new + obj = klass.new + sclass = obj.singleton_class + + -> { sclass.send :undef_method, :not_exist }.should raise_error(NameError, /undefined method `not_exist' for class `#{sclass}'/) { |e| + e.message.should include('`# { klass.send :undef_method, :not_exist }.should raise_error(NameError, /undefined method `not_exist' for class `String'/) { |e| # a NameError and not a NoMethodError e.class.should == NameError } diff --git a/spec/ruby/core/process/clock_getres_spec.rb b/spec/ruby/core/process/clock_getres_spec.rb index 7112b0520a..f1ecb74010 100644 --- a/spec/ruby/core/process/clock_getres_spec.rb +++ b/spec/ruby/core/process/clock_getres_spec.rb @@ -8,10 +8,7 @@ describe "Process.clock_getres" do # NOTE: Look at fixtures/clocks.rb for clock and OS-specific exclusions ProcessSpecs.clock_constants_for_resolution_checks.each do |name, value| it "matches the clock in practice for Process::#{name}" do - times = [] - 10_000.times do - times << Process.clock_gettime(value, :nanosecond) - end + times = 10_000.times.map { Process.clock_gettime(value, :nanosecond) } reported = Process.clock_getres(value, :nanosecond) # The clock should not be more accurate than reported (times should be diff --git a/spec/ruby/core/process/clock_gettime_spec.rb b/spec/ruby/core/process/clock_gettime_spec.rb index d3f973d7ae..59e1406e02 100644 --- a/spec/ruby/core/process/clock_gettime_spec.rb +++ b/spec/ruby/core/process/clock_gettime_spec.rb @@ -41,4 +41,97 @@ describe "Process.clock_gettime" do t2.should be_close(t1, TIME_TOLERANCE) end end + + describe "supports the platform clocks mentioned in the documentation" do + it "CLOCK_REALTIME" do + Process.clock_gettime(Process::CLOCK_REALTIME).should be_an_instance_of(Float) + end + + it "CLOCK_MONOTONIC" do + Process.clock_gettime(Process::CLOCK_MONOTONIC).should be_an_instance_of(Float) + end + + # These specs need macOS 10.12+ / darwin 16+ + guard_not -> { platform_is_not(:darwin) or RUBY_PLATFORM[/darwin\d+/].to_i >= 16 } do + platform_is :linux, :openbsd, :darwin do + it "CLOCK_PROCESS_CPUTIME_ID" do + Process.clock_gettime(Process::CLOCK_PROCESS_CPUTIME_ID).should be_an_instance_of(Float) + end + end + + platform_is :linux, :freebsd, :openbsd, :darwin do + it "CLOCK_THREAD_CPUTIME_ID" do + Process.clock_gettime(Process::CLOCK_THREAD_CPUTIME_ID).should be_an_instance_of(Float) + end + end + + platform_is :freebsd, :openbsd do + it "CLOCK_VIRTUAL" do + Process.clock_gettime(Process::CLOCK_VIRTUAL).should be_an_instance_of(Float) + end + + it "CLOCK_PROF" do + Process.clock_gettime(Process::CLOCK_PROF).should be_an_instance_of(Float) + end + + it "CLOCK_UPTIME" do + Process.clock_gettime(Process::CLOCK_UPTIME).should be_an_instance_of(Float) + end + end + + platform_is :linux, :darwin do + it "CLOCK_MONOTONIC_RAW" do + Process.clock_gettime(Process::CLOCK_MONOTONIC_RAW).should be_an_instance_of(Float) + end + end + + platform_is :darwin do + it "CLOCK_MONOTONIC_RAW_APPROX" do + Process.clock_gettime(Process::CLOCK_MONOTONIC_RAW_APPROX).should be_an_instance_of(Float) + end + + it "CLOCK_UPTIME_RAW and CLOCK_UPTIME_RAW_APPROX" do + Process.clock_gettime(Process::CLOCK_UPTIME_RAW).should be_an_instance_of(Float) + Process.clock_gettime(Process::CLOCK_UPTIME_RAW_APPROX).should be_an_instance_of(Float) + end + end + + platform_is :freebsd do + it "CLOCK_REALTIME_FAST and CLOCK_REALTIME_PRECISE" do + Process.clock_gettime(Process::CLOCK_REALTIME_FAST).should be_an_instance_of(Float) + Process.clock_gettime(Process::CLOCK_REALTIME_PRECISE).should be_an_instance_of(Float) + end + + it "CLOCK_MONOTONIC_FAST and CLOCK_MONOTONIC_PRECISE" do + Process.clock_gettime(Process::CLOCK_MONOTONIC_FAST).should be_an_instance_of(Float) + Process.clock_gettime(Process::CLOCK_MONOTONIC_PRECISE).should be_an_instance_of(Float) + end + + it "CLOCK_UPTIME_FAST and CLOCK_UPTIME_PRECISE" do + Process.clock_gettime(Process::CLOCK_UPTIME_FAST).should be_an_instance_of(Float) + Process.clock_gettime(Process::CLOCK_UPTIME_PRECISE).should be_an_instance_of(Float) + end + + it "CLOCK_SECOND" do + Process.clock_gettime(Process::CLOCK_SECOND).should be_an_instance_of(Float) + end + end + + platform_is :linux do + it "CLOCK_REALTIME_COARSE and CLOCK_REALTIME_ALARM" do + Process.clock_gettime(Process::CLOCK_REALTIME_COARSE).should be_an_instance_of(Float) + Process.clock_gettime(Process::CLOCK_REALTIME_ALARM).should be_an_instance_of(Float) + end + + it "CLOCK_MONOTONIC_COARSE" do + Process.clock_gettime(Process::CLOCK_MONOTONIC_COARSE).should be_an_instance_of(Float) + end + + it "CLOCK_BOOTTIME and CLOCK_BOOTTIME_ALARM" do + Process.clock_gettime(Process::CLOCK_BOOTTIME).should be_an_instance_of(Float) + Process.clock_gettime(Process::CLOCK_BOOTTIME_ALARM).should be_an_instance_of(Float) + end + end + end + end end diff --git a/spec/ruby/core/process/exec_spec.rb b/spec/ruby/core/process/exec_spec.rb index 848990c6dc..5a6e3fc1a4 100644 --- a/spec/ruby/core/process/exec_spec.rb +++ b/spec/ruby/core/process/exec_spec.rb @@ -200,9 +200,9 @@ describe "Process.exec" do it "maps the key to a file descriptor in the child that inherits the file descriptor from the parent specified by the value" do map_fd_fixture = fixture __FILE__, "map_fd.rb" cmd = <<-EOC - f = File.open("#{@name}", "w+") + f = File.open(#{@name.inspect}, "w+") child_fd = f.fileno + 1 - File.open("#{@child_fd_file}", "w") { |io| io.print child_fd } + File.open(#{@child_fd_file.inspect}, "w") { |io| io.print child_fd } Process.exec "#{ruby_cmd(map_fd_fixture)} \#{child_fd}", { child_fd => f } EOC @@ -212,6 +212,35 @@ describe "Process.exec" do File.read(@name).should == "writing to fd: #{child_fd}" end + + it "lets the process after exec have specified file descriptor despite close_on_exec" do + map_fd_fixture = fixture __FILE__, "map_fd.rb" + cmd = <<-EOC + f = File.open(#{@name.inspect}, 'w+') + puts(f.fileno, f.close_on_exec?) + STDOUT.flush + Process.exec("#{ruby_cmd(map_fd_fixture)} \#{f.fileno}", f.fileno => f.fileno) + EOC + + output = ruby_exe(cmd, escape: true) + child_fd, close_on_exec = output.split + + child_fd.to_i.should > STDERR.fileno + close_on_exec.should == 'true' + File.read(@name).should == "writing to fd: #{child_fd}" + end + + it "sets close_on_exec to false on specified fd even when it fails" do + cmd = <<-EOC + f = File.open(#{__FILE__.inspect}, 'r') + puts(f.close_on_exec?) + Process.exec('/', f.fileno => f.fileno) rescue nil + puts(f.close_on_exec?) + EOC + + output = ruby_exe(cmd, escape: true) + output.split.should == ['true', 'false'] + end end end end diff --git a/spec/ruby/core/process/fixtures/common.rb b/spec/ruby/core/process/fixtures/common.rb index bdbf1e654b..f49513d262 100644 --- a/spec/ruby/core/process/fixtures/common.rb +++ b/spec/ruby/core/process/fixtures/common.rb @@ -3,11 +3,15 @@ module ProcessSpecs if defined?(MSpecScript::SYSTEM_RUBY) context.send(:before, :all) do @ruby = ::RUBY_EXE - Object.const_set(:RUBY_EXE, MSpecScript::SYSTEM_RUBY) + suppress_warning { + Object.const_set(:RUBY_EXE, MSpecScript::SYSTEM_RUBY) + } end context.send(:after, :all) do - Object.const_set(:RUBY_EXE, @ruby) + suppress_warning { + Object.const_set(:RUBY_EXE, @ruby) + } end end end diff --git a/spec/ruby/core/process/status/equal_value_spec.rb b/spec/ruby/core/process/status/equal_value_spec.rb index 9e9a2d0a2b..444ce1775b 100644 --- a/spec/ruby/core/process/status/equal_value_spec.rb +++ b/spec/ruby/core/process/status/equal_value_spec.rb @@ -1,5 +1,15 @@ require_relative '../../../spec_helper' describe "Process::Status#==" do - it "needs to be reviewed for spec completeness" + it "returns true when compared to the integer status of an exited child" do + ruby_exe("exit(29)") + $?.to_i.should == $? + $?.should == $?.to_i + end + + it "returns true when compared to the integer status of a terminated child" do + ruby_exe("Process.kill(:KILL, $$); exit(29)") + $?.to_i.should == $? + $?.should == $?.to_i + end end diff --git a/spec/ruby/core/process/status/exitstatus_spec.rb b/spec/ruby/core/process/status/exitstatus_spec.rb index cd46b2081f..d6c6965b9e 100644 --- a/spec/ruby/core/process/status/exitstatus_spec.rb +++ b/spec/ruby/core/process/status/exitstatus_spec.rb @@ -11,7 +11,7 @@ describe "Process::Status#exitstatus" do describe "for a child that raised SignalException" do before :each do - ruby_exe("raise SignalException, 'SIGTERM'") + ruby_exe("Process.kill(:KILL, $$); exit(42)") end platform_is_not :windows do diff --git a/spec/ruby/core/process/status/termsig_spec.rb b/spec/ruby/core/process/status/termsig_spec.rb index 1482d27146..204708bc1b 100644 --- a/spec/ruby/core/process/status/termsig_spec.rb +++ b/spec/ruby/core/process/status/termsig_spec.rb @@ -1,9 +1,7 @@ require_relative '../../../spec_helper' describe "Process::Status#termsig" do - describe "for a child that exited normally" do - before :each do ruby_exe("exit(0)") end @@ -26,26 +24,20 @@ describe "Process::Status#termsig" do end describe "for a child that was sent a signal" do - before :each do ruby_exe("Process.kill(:KILL, $$); exit(42)") end platform_is_not :windows do - it "returns the signal" do $?.termsig.should == Signal.list["KILL"] end - end platform_is :windows do - it "always returns nil" do $?.termsig.should be_nil end - end - end end diff --git a/spec/ruby/core/process/status/to_i_spec.rb b/spec/ruby/core/process/status/to_i_spec.rb index 37b7bdb1e4..a284f64f86 100644 --- a/spec/ruby/core/process/status/to_i_spec.rb +++ b/spec/ruby/core/process/status/to_i_spec.rb @@ -1,5 +1,13 @@ require_relative '../../../spec_helper' describe "Process::Status#to_i" do - it "needs to be reviewed for spec completeness" + it "returns an integer when the child exits" do + ruby_exe('exit 48') + $?.to_i.should be_an_instance_of(Integer) + end + + it "returns an integer when the child is signaled" do + ruby_exe('raise SignalException, "TERM"') + $?.to_i.should be_an_instance_of(Integer) + end end diff --git a/spec/ruby/core/process/times_spec.rb b/spec/ruby/core/process/times_spec.rb index 07b4fa5c9f..f148954262 100644 --- a/spec/ruby/core/process/times_spec.rb +++ b/spec/ruby/core/process/times_spec.rb @@ -7,21 +7,19 @@ describe "Process.times" do it "returns current cpu times" do t = Process.times + user = t.utime - # Do busy work for a wall-clock interval. - start = Time.now - 1 until (Time.now - start) > 0.5 + 1 until Process.times.utime > user + Process.times.utime.should > user + end - # Ensure times is larger. NOTE that there is no - # guarantee of an upper bound since anything may be - # happening at the OS level, so we ONLY check that at - # least an interval has elapsed. Also, we are assuming - # there is a correlation between wall clock time and - # process time. In practice, there is an observed - # discrepancy often 10% or greater. In other words, - # this is a very fuzzy test. - t2 = Process.times - diff = (t2.utime + t2.stime) - (t.utime + t.stime) - diff.should > 0 + ruby_version_is "2.5" do + platform_is_not :windows do + it "uses getrusage when available to improve precision beyond milliseconds" do + times = 100.times.map { Process.times } + times.count { |t| ((t.utime * 1e6).to_i % 1000) > 0 }.should > 0 + times.count { |t| ((t.stime * 1e6).to_i % 1000) > 0 }.should > 0 + end + end end end diff --git a/spec/ruby/core/process/tms/cstime_spec.rb b/spec/ruby/core/process/tms/cstime_spec.rb deleted file mode 100644 index 207d4391c0..0000000000 --- a/spec/ruby/core/process/tms/cstime_spec.rb +++ /dev/null @@ -1,9 +0,0 @@ -require_relative '../../../spec_helper' - -describe "Process::Tms#cstime" do - it "needs to be reviewed for spec completeness" -end - -describe "Process::Tms#cstime=" do - it "needs to be reviewed for spec completeness" -end diff --git a/spec/ruby/core/process/tms/cutime_spec.rb b/spec/ruby/core/process/tms/cutime_spec.rb deleted file mode 100644 index 390280f005..0000000000 --- a/spec/ruby/core/process/tms/cutime_spec.rb +++ /dev/null @@ -1,9 +0,0 @@ -require_relative '../../../spec_helper' - -describe "Process::Tms#cutime" do - it "needs to be reviewed for spec completeness" -end - -describe "Process::Tms#cutime=" do - it "needs to be reviewed for spec completeness" -end diff --git a/spec/ruby/core/process/tms/element_reference_spec.rb b/spec/ruby/core/process/tms/element_reference_spec.rb deleted file mode 100644 index 84a34089ae..0000000000 --- a/spec/ruby/core/process/tms/element_reference_spec.rb +++ /dev/null @@ -1,5 +0,0 @@ -require_relative '../../../spec_helper' - -describe "Process::Tms.[]" do - it "needs to be reviewed for spec completeness" -end diff --git a/spec/ruby/core/process/tms/members_spec.rb b/spec/ruby/core/process/tms/members_spec.rb deleted file mode 100644 index 005a8baec1..0000000000 --- a/spec/ruby/core/process/tms/members_spec.rb +++ /dev/null @@ -1,5 +0,0 @@ -require_relative '../../../spec_helper' - -describe "Process::Tms.members" do - it "needs to be reviewed for spec completeness" -end diff --git a/spec/ruby/core/process/tms/new_spec.rb b/spec/ruby/core/process/tms/new_spec.rb deleted file mode 100644 index 9dd1f5a8f2..0000000000 --- a/spec/ruby/core/process/tms/new_spec.rb +++ /dev/null @@ -1,5 +0,0 @@ -require_relative '../../../spec_helper' - -describe "Process::Tms.new" do - it "needs to be reviewed for spec completeness" -end diff --git a/spec/ruby/core/process/tms/stime_spec.rb b/spec/ruby/core/process/tms/stime_spec.rb deleted file mode 100644 index 4104b625e2..0000000000 --- a/spec/ruby/core/process/tms/stime_spec.rb +++ /dev/null @@ -1,9 +0,0 @@ -require_relative '../../../spec_helper' - -describe "Process::Tms#stime" do - it "needs to be reviewed for spec completeness" -end - -describe "Process::Tms#stime=" do - it "needs to be reviewed for spec completeness" -end diff --git a/spec/ruby/core/process/tms/utime_spec.rb b/spec/ruby/core/process/tms/utime_spec.rb deleted file mode 100644 index 28371590e9..0000000000 --- a/spec/ruby/core/process/tms/utime_spec.rb +++ /dev/null @@ -1,9 +0,0 @@ -require_relative '../../../spec_helper' - -describe "Process::Tms#utime" do - it "needs to be reviewed for spec completeness" -end - -describe "Process::Tms#utime=" do - it "needs to be reviewed for spec completeness" -end diff --git a/spec/ruby/core/regexp/match_spec.rb b/spec/ruby/core/regexp/match_spec.rb index 0ce8347d2d..f31b893f5e 100644 --- a/spec/ruby/core/regexp/match_spec.rb +++ b/spec/ruby/core/regexp/match_spec.rb @@ -38,6 +38,10 @@ describe "Regexp#match" do -> { Regexp.allocate.match('foo') }.should raise_error(TypeError) end + it "raises TypeError on an uninitialized Regexp" do + -> { Regexp.allocate.match('foo'.encode("UTF-16LE")) }.should raise_error(TypeError) + end + describe "with [string, position]" do describe "when given a positive position" do it "matches the input at a given position" do diff --git a/spec/ruby/core/struct/clone_spec.rb b/spec/ruby/core/struct/clone_spec.rb new file mode 100644 index 0000000000..40c4d52d57 --- /dev/null +++ b/spec/ruby/core/struct/clone_spec.rb @@ -0,0 +1,7 @@ +require_relative '../../spec_helper' +require_relative 'fixtures/classes' +require_relative 'shared/dup' + +describe "Struct-based class#clone" do + it_behaves_like :struct_dup, :clone +end diff --git a/spec/ruby/core/struct/dup_spec.rb b/spec/ruby/core/struct/dup_spec.rb index cb54b7ceee..8b50c39014 100644 --- a/spec/ruby/core/struct/dup_spec.rb +++ b/spec/ruby/core/struct/dup_spec.rb @@ -1,8 +1,11 @@ require_relative '../../spec_helper' require_relative 'fixtures/classes' +require_relative 'shared/dup' describe "Struct-based class#dup" do + it_behaves_like :struct_dup, :dup + # From https://github.com/jruby/jruby/issues/3686 it "retains an included module in the ancestor chain for the struct's singleton class" do klass = Struct.new(:foo) diff --git a/spec/ruby/core/struct/instance_variable_get_spec.rb b/spec/ruby/core/struct/instance_variable_get_spec.rb new file mode 100644 index 0000000000..e4a3ea87dc --- /dev/null +++ b/spec/ruby/core/struct/instance_variable_get_spec.rb @@ -0,0 +1,16 @@ +require_relative '../../spec_helper' +require_relative 'fixtures/classes' + +describe "Struct#instance_variable_get" do + it "returns nil for attributes" do + car = StructClasses::Car.new("Hugo", "Foo", "1972") + car.instance_variable_get(:@make).should be_nil + end + + it "returns a user value for variables with the same name as attributes" do + car = StructClasses::Car.new("Hugo", "Foo", "1972") + car.instance_variable_set :@make, "explicit" + car.instance_variable_get(:@make).should == "explicit" + car.make.should == "Hugo" + end +end diff --git a/spec/ruby/core/struct/new_spec.rb b/spec/ruby/core/struct/new_spec.rb index f888106950..564c49af01 100644 --- a/spec/ruby/core/struct/new_spec.rb +++ b/spec/ruby/core/struct/new_spec.rb @@ -74,6 +74,10 @@ describe "Struct.new" do end end + it "raises ArgumentError when there is a duplicate member" do + -> { Struct.new(:foo, :foo) }.should raise_error(ArgumentError, "duplicate member: foo") + end + it "raises a TypeError if object is not a Symbol" do obj = mock(':ruby') def obj.to_sym() :ruby end @@ -147,7 +151,6 @@ describe "Struct.new" do context "keyword_init: true option" do before :all do @struct_with_kwa = Struct.new(:name, :legs, keyword_init: true) - @struct_without_kwa = Struct.new(:name, :legs, keyword_init: false) end it "creates a class that accepts keyword arguments to initialize" do @@ -156,6 +159,10 @@ describe "Struct.new" do obj.legs.should == 4 end + it "raises when there is a duplicate member" do + -> { Struct.new(:foo, :foo, keyword_init: true) }.should raise_error(ArgumentError, "duplicate member: foo") + end + describe "new class instantiation" do it "accepts arguments as hash as well" do obj = @struct_with_kwa.new({name: "elefant", legs: 4}) @@ -163,6 +170,18 @@ describe "Struct.new" do obj.legs.should == 4 end + it "allows missing arguments" do + obj = @struct_with_kwa.new(name: "elefant") + obj.name.should == "elefant" + obj.legs.should be_nil + end + + it "allows no arguments" do + obj = @struct_with_kwa.new + obj.name.should be_nil + obj.legs.should be_nil + end + it "raises ArgumentError when passed not declared keyword argument" do -> { @struct_with_kwa.new(name: "elefant", legs: 4, foo: "bar") @@ -184,6 +203,10 @@ describe "Struct.new" do end context "keyword_init: false option" do + before :all do + @struct_without_kwa = Struct.new(:name, :legs, keyword_init: false) + end + it "behaves like it does without :keyword_init option" do obj = @struct_without_kwa.new("elefant", 4) obj.name.should == "elefant" diff --git a/spec/ruby/core/struct/shared/dup.rb b/spec/ruby/core/struct/shared/dup.rb new file mode 100644 index 0000000000..994f3f443e --- /dev/null +++ b/spec/ruby/core/struct/shared/dup.rb @@ -0,0 +1,9 @@ +describe :struct_dup, shared: true do + it "duplicates members" do + klass = Struct.new(:foo, :bar) + instance = klass.new(14, 2) + duped = instance.send(@method) + duped.foo.should == 14 + duped.bar.should == 2 + end +end diff --git a/spec/ruby/core/time/new_spec.rb b/spec/ruby/core/time/new_spec.rb index dcdd83a085..01ee47faa1 100644 --- a/spec/ruby/core/time/new_spec.rb +++ b/spec/ruby/core/time/new_spec.rb @@ -113,6 +113,12 @@ describe "Time.new with a utc_offset argument" do it "raises ArgumentError if the utc_offset argument is greater than or equal to 10e9" do -> { Time.new(2000, 1, 1, 0, 0, 0, 1000000000) }.should raise_error(ArgumentError) end + + it "raises ArgumentError if the month is greater than 12" do + # For some reason MRI uses a different message for month in 13-15 and month>=16 + -> { Time.new(2000, 13, 1, 0, 0, 0, "+01:00") }.should raise_error(ArgumentError, /(mon|argument) out of range/) + -> { Time.new(2000, 16, 1, 0, 0, 0, "+01:00") }.should raise_error(ArgumentError, "argument out of range") + end end ruby_version_is "2.6" do diff --git a/spec/ruby/fixtures/code/wrap_fixture.rb b/spec/ruby/fixtures/code/wrap_fixture.rb index b83a8970d7..7ddf5a62e0 100644 --- a/spec/ruby/fixtures/code/wrap_fixture.rb +++ b/spec/ruby/fixtures/code/wrap_fixture.rb @@ -1,3 +1,9 @@ class LoadSpecWrap - ScratchPad << self + ScratchPad << String end + +def load_wrap_specs_top_level_method +end +ScratchPad << method(:load_wrap_specs_top_level_method).owner + +ScratchPad << self diff --git a/spec/ruby/language/match_spec.rb b/spec/ruby/language/match_spec.rb index 36d347bd57..ebf677cabc 100644 --- a/spec/ruby/language/match_spec.rb +++ b/spec/ruby/language/match_spec.rb @@ -48,6 +48,13 @@ describe "The =~ operator with named captures" do end end + describe "on syntax of 'string_literal' =~ /regexp/" do + it "does not set local variables" do + 'string literal' =~ /(?str)(?lit)?/ + local_variables.should == [] + end + end + describe "on syntax of string_variable =~ /regexp/" do it "does not set local variables" do @string =~ /(?foo)(?bar)?/ diff --git a/spec/ruby/language/regexp/encoding_spec.rb b/spec/ruby/language/regexp/encoding_spec.rb index dce64a4753..b8559c6b27 100644 --- a/spec/ruby/language/regexp/encoding_spec.rb +++ b/spec/ruby/language/regexp/encoding_spec.rb @@ -42,6 +42,10 @@ describe "Regexps with encoding modifiers" do /./n.encoding.should == Encoding::US_ASCII end + it 'uses BINARY when is not initialized' do + Regexp.allocate.encoding.should == Encoding::BINARY + end + it 'uses BINARY as /n encoding if not all chars are 7-bit' do /\xFF/n.encoding.should == Encoding::BINARY end @@ -100,4 +104,16 @@ describe "Regexps with encoding modifiers" do it "selects last of multiple encoding specifiers" do /foo/ensuensuens.should == /foo/s end + + it "raises Encoding::CompatibilityError when trying match against different encodings" do + -> { /\A[[:space:]]*\z/.match(" ".encode("UTF-16LE")) }.should raise_error(Encoding::CompatibilityError) + end + + it "raises Encoding::CompatibilityError when trying match? against different encodings" do + -> { /\A[[:space:]]*\z/.match?(" ".encode("UTF-16LE")) }.should raise_error(Encoding::CompatibilityError) + end + + it "raises Encoding::CompatibilityError when trying =~ against different encodings" do + -> { /\A[[:space:]]*\z/ =~ " ".encode("UTF-16LE") }.should raise_error(Encoding::CompatibilityError) + end end diff --git a/spec/ruby/library/base64/decode64_spec.rb b/spec/ruby/library/base64/decode64_spec.rb index 3b81203588..f6cd26d788 100644 --- a/spec/ruby/library/base64/decode64_spec.rb +++ b/spec/ruby/library/base64/decode64_spec.rb @@ -6,4 +6,20 @@ describe "Base64#decode64" do it "returns the Base64-decoded version of the given string" do Base64.decode64("U2VuZCByZWluZm9yY2VtZW50cw==\n").should == "Send reinforcements" end + + it "returns the Base64-decoded version of the given shared string" do + Base64.decode64("base64: U2VuZCByZWluZm9yY2VtZW50cw==\n".split(" ").last).should == "Send reinforcements" + end + + it "returns the Base64-decoded version of the given string with wrong padding" do + Base64.decode64("XU2VuZCByZWluZm9yY2VtZW50cw===").should == "]M\x95\xB9\x90\x81\xC9\x95\xA5\xB9\x99\xBD\xC9\x8D\x95\xB5\x95\xB9\xD1\xCC".b + end + + it "returns the Base64-decoded version of the given string that contains an invalid character" do + Base64.decode64("%3D").should == "\xDC".b + end + + it "returns a binary encoded string" do + Base64.decode64("SEk=").encoding.should == Encoding::BINARY + end end diff --git a/spec/ruby/library/base64/encode64_spec.rb b/spec/ruby/library/base64/encode64_spec.rb index 91ac41bed0..64de6257bc 100644 --- a/spec/ruby/library/base64/encode64_spec.rb +++ b/spec/ruby/library/base64/encode64_spec.rb @@ -11,4 +11,13 @@ describe "Base64#encode64" do it "returns the Base64-encoded version of the given string" do Base64.encode64('Send reinforcements').should == "U2VuZCByZWluZm9yY2VtZW50cw==\n" end + + it "returns the Base64-encoded version of the given shared string" do + Base64.encode64("Now is the time for all good coders\nto learn Ruby".split("\n").last).should == + "dG8gbGVhcm4gUnVieQ==\n" + end + + it "returns a US_ASCII encoded string" do + Base64.encode64("HI").encoding.should == Encoding::US_ASCII + end end diff --git a/spec/ruby/library/base64/strict_decode64_spec.rb b/spec/ruby/library/base64/strict_decode64_spec.rb new file mode 100644 index 0000000000..d258223c82 --- /dev/null +++ b/spec/ruby/library/base64/strict_decode64_spec.rb @@ -0,0 +1,41 @@ +require_relative '../../spec_helper' + +require 'base64' + +describe "Base64#strict_decode64" do + it "returns the Base64-decoded version of the given string" do + Base64.strict_decode64("U2VuZCByZWluZm9yY2VtZW50cw==").should == "Send reinforcements" + end + + it "returns the Base64-decoded version of the given shared string" do + Base64.strict_decode64("base64: U2VuZCByZWluZm9yY2VtZW50cw==".split(" ").last).should == "Send reinforcements" + end + + it "raises ArgumentError when the given string contains CR" do + -> do + Base64.strict_decode64("U2VuZCByZWluZm9yY2VtZW50cw==\r") + end.should raise_error(ArgumentError) + end + + it "raises ArgumentError when the given string contains LF" do + -> do + Base64.strict_decode64("U2VuZCByZWluZm9yY2VtZW50cw==\n") + end.should raise_error(ArgumentError) + end + + it "raises ArgumentError when the given string has wrong padding" do + -> do + Base64.strict_decode64("=U2VuZCByZWluZm9yY2VtZW50cw==") + end.should raise_error(ArgumentError) + end + + it "raises ArgumentError when the given string contains an invalid character" do + -> do + Base64.strict_decode64("%3D") + end.should raise_error(ArgumentError) + end + + it "returns a binary encoded string" do + Base64.strict_decode64("SEk=").encoding.should == Encoding::BINARY + end +end diff --git a/spec/ruby/library/base64/strict_encode64_spec.rb b/spec/ruby/library/base64/strict_encode64_spec.rb new file mode 100644 index 0000000000..7cabcf190c --- /dev/null +++ b/spec/ruby/library/base64/strict_encode64_spec.rb @@ -0,0 +1,19 @@ +require_relative '../../spec_helper' + +require 'base64' + +describe "Base64#strict_encode64" do + it "returns the Base64-encoded version of the given string" do + Base64.strict_encode64("Now is the time for all good coders\nto learn Ruby").should == + "Tm93IGlzIHRoZSB0aW1lIGZvciBhbGwgZ29vZCBjb2RlcnMKdG8gbGVhcm4gUnVieQ==" + end + + it "returns the Base64-encoded version of the given shared string" do + Base64.strict_encode64("Now is the time for all good coders\nto learn Ruby".split("\n").last).should == + "dG8gbGVhcm4gUnVieQ==" + end + + it "returns a US_ASCII encoded string" do + Base64.strict_encode64("HI").encoding.should == Encoding::US_ASCII + end +end diff --git a/spec/ruby/library/bigdecimal/BigDecimal_spec.rb b/spec/ruby/library/bigdecimal/BigDecimal_spec.rb index e1e6fe9fb1..179bde1aed 100644 --- a/spec/ruby/library/bigdecimal/BigDecimal_spec.rb +++ b/spec/ruby/library/bigdecimal/BigDecimal_spec.rb @@ -24,6 +24,12 @@ describe "Kernel#BigDecimal" do } end + it "BigDecimal(Rational) with bigger-than-double numerator" do + rational = 99999999999999999999/100r + rational.numerator.should > 2**64 + BigDecimal(rational, 100).to_s.should == "0.99999999999999999999e18" + end + it "accepts significant digits >= given precision" do BigDecimal("3.1415923", 10).precs[1].should >= 10 end @@ -33,8 +39,8 @@ describe "Kernel#BigDecimal" do BigDecimal(pi_string).precs[1].should >= pi_string.size-1 end - it "ignores leading whitespace" do - BigDecimal(" \t\n \r1234").should == BigDecimal("1234") + it "ignores leading and trailing whitespace" do + BigDecimal(" \t\n \r1234\t\r\n ").should == BigDecimal("1234") BigDecimal(" \t\n \rNaN \n").nan?.should == true BigDecimal(" \t\n \rInfinity \n").infinite?.should == 1 BigDecimal(" \t\n \r-Infinity \n").infinite?.should == -1 @@ -159,4 +165,93 @@ describe "Kernel#BigDecimal" do BigDecimal(0.0, Float::DIG).sign.should == 1 end + it "pre-coerces long integers" do + BigDecimal(3).add(1 << 50, 3).should == BigDecimal('0.113e16') + end + + describe "when interacting with Rational" do + before :each do + @a = BigDecimal('166.666666666') + @b = Rational(500, 3) + @c = @a - @b + end + + # Check the input is as we understand it + + it "has the LHS print as expected" do + @a.to_s.should == "0.166666666666e3" + @a.to_f.to_s.should == "166.666666666" + Float(@a).to_s.should == "166.666666666" + end + + it "has the RHS print as expected" do + @b.to_s.should == "500/3" + @b.to_f.to_s.should == "166.66666666666666" + Float(@b).to_s.should == "166.66666666666666" + end + + it "has the expected precision on the LHS" do + @a.precs[0].should == 18 + end + + it "has the expected maximum precision on the LHS" do + @a.precs[1].should == 27 + end + + it "produces the expected result when done via Float" do + (Float(@a) - Float(@b)).to_s.should == "-6.666596163995564e-10" + end + + it "produces the expected result when done via to_f" do + (@a.to_f - @b.to_f).to_s.should == "-6.666596163995564e-10" + end + + # Check underlying methods work as we understand + + it "BigDecimal precision is the number of digits rounded up to a multiple of nine" do + 1.upto(100) do |n| + b = BigDecimal('4' * n) + precs, _ = b.precs + (precs >= 9).should be_true + (precs >= n).should be_true + (precs % 9).should == 0 + end + BigDecimal('NaN').precs[0].should == 9 + end + + it "BigDecimal maximum precision is nine more than precision except for abnormals" do + 1.upto(100) do |n| + b = BigDecimal('4' * n) + precs, max = b.precs + max.should == precs + 9 + end + BigDecimal('NaN').precs[1].should == 9 + end + + it "BigDecimal(Rational, 18) produces the result we expect" do + BigDecimal(@b, 18).to_s.should == "0.166666666666666667e3" + end + + it "BigDecimal(Rational, BigDecimal.precs[0]) produces the result we expect" do + BigDecimal(@b, @a.precs[0]).to_s.should == "0.166666666666666667e3" + end + + # Check the top-level expression works as we expect + + it "produces a BigDecimal" do + @c.class.should == BigDecimal + end + + it "produces the expected result" do + @c.should == BigDecimal("-0.666667e-9") + @c.to_s.should == "-0.666667e-9" + end + + it "produces the correct class for other arithmetic operators" do + (@a + @b).class.should == BigDecimal + (@a * @b).class.should == BigDecimal + (@a / @b).class.should == BigDecimal + (@a % @b).class.should == BigDecimal + end + end end diff --git a/spec/ruby/library/conditionvariable/signal_spec.rb b/spec/ruby/library/conditionvariable/signal_spec.rb index 0dafe8527f..04b249a6c6 100644 --- a/spec/ruby/library/conditionvariable/signal_spec.rb +++ b/spec/ruby/library/conditionvariable/signal_spec.rb @@ -66,4 +66,39 @@ describe "ConditionVariable#signal" do # released in the same order r2.should == r1 end + + it "allows control to be passed between a pair of threads" do + m = Mutex.new + cv = ConditionVariable.new + repeats = 100 + in_synchronize = false + + t1 = Thread.new do + m.synchronize do + in_synchronize = true + repeats.times do + cv.wait(m) + cv.signal + end + end + end + + # Make sure t1 is waiting for a signal before launching t2. + Thread.pass until in_synchronize + Thread.pass until t1.status == 'sleep' + + t2 = Thread.new do + m.synchronize do + repeats.times do + cv.signal + cv.wait(m) + end + end + end + + # Check that both threads terminated without exception + t1.join + t2.join + m.locked?.should == false + end end diff --git a/spec/ruby/library/coverage/result_spec.rb b/spec/ruby/library/coverage/result_spec.rb index ebfa5538b4..9b84530076 100644 --- a/spec/ruby/library/coverage/result_spec.rb +++ b/spec/ruby/library/coverage/result_spec.rb @@ -35,8 +35,9 @@ describe 'Coverage.result' do Coverage.start require @class_file.chomp('.rb') Coverage.result - -> { Coverage.result } - .should raise_error(RuntimeError, 'coverage measurement is not enabled') + -> { + Coverage.result + }.should raise_error(RuntimeError, 'coverage measurement is not enabled') end it 'second run should give same result' do diff --git a/spec/ruby/library/date/iso8601_spec.rb b/spec/ruby/library/date/iso8601_spec.rb index 21b0a4cedd..2c698db514 100644 --- a/spec/ruby/library/date/iso8601_spec.rb +++ b/spec/ruby/library/date/iso8601_spec.rb @@ -35,3 +35,10 @@ describe "Date.iso8601" do -> { Date.iso8601(Object.new) }.should raise_error(TypeError) end end + +describe "Date._iso8601" do + it "returns an empty hash if the argument is a invalid Date" do + h = Date._iso8601('invalid') + h.should == {} + end +end diff --git a/spec/ruby/library/date/rfc3339_spec.rb b/spec/ruby/library/date/rfc3339_spec.rb new file mode 100644 index 0000000000..a8711d47b2 --- /dev/null +++ b/spec/ruby/library/date/rfc3339_spec.rb @@ -0,0 +1,13 @@ +require_relative '../../spec_helper' +require 'date' + +describe "Date.rfc3339" do + it "needs to be reviewed for spec completeness" +end + +describe "Date._rfc3339" do + it "returns an empty hash if the argument is a invalid Date" do + h = Date._rfc3339('invalid') + h.should == {} + end +end diff --git a/spec/ruby/library/mkmf/mkmf_spec.rb b/spec/ruby/library/mkmf/mkmf_spec.rb new file mode 100644 index 0000000000..18b090e703 --- /dev/null +++ b/spec/ruby/library/mkmf/mkmf_spec.rb @@ -0,0 +1,7 @@ +require_relative '../../spec_helper' + +describe 'mkmf' do + it 'can be required with --enable-frozen-string-literal' do + ruby_exe('p MakeMakefile', options: '-rmkmf --enable-frozen-string-literal').should == "MakeMakefile\n" + end +end diff --git a/spec/ruby/library/rbconfig/rbconfig_spec.rb b/spec/ruby/library/rbconfig/rbconfig_spec.rb index 7c3fbf6c58..35b465d106 100644 --- a/spec/ruby/library/rbconfig/rbconfig_spec.rb +++ b/spec/ruby/library/rbconfig/rbconfig_spec.rb @@ -23,6 +23,18 @@ describe 'RbConfig::CONFIG' do File.should.exist?("#{archdir}/etc.#{RbConfig::CONFIG['DLEXT']}") end end + + it "contains no frozen strings even with --enable-frozen-string-literal" do + ruby_exe(<<-RUBY, options: '--enable-frozen-string-literal').should == "Done\n" + require 'rbconfig' + RbConfig::CONFIG.each do |k, v| + if v.frozen? + puts "\#{k} Failure" + end + end + puts 'Done' + RUBY + end end describe "RbConfig::TOPDIR" do diff --git a/spec/ruby/library/rbconfig/sizeof/limits_spec.rb b/spec/ruby/library/rbconfig/sizeof/limits_spec.rb new file mode 100644 index 0000000000..a026135eee --- /dev/null +++ b/spec/ruby/library/rbconfig/sizeof/limits_spec.rb @@ -0,0 +1,42 @@ +require_relative '../../../spec_helper' +require 'rbconfig/sizeof' + +ruby_version_is "2.5" do + describe "RbConfig::LIMITS" do + it "is a Hash" do + RbConfig::LIMITS.should be_kind_of(Hash) + end + + it "has string keys and numeric values" do + RbConfig::LIMITS.each do |key, value| + key.should be_kind_of String + value.should be_kind_of Numeric + end + end + + it "contains FIXNUM_MIN and FIXNUM_MAX" do + RbConfig::LIMITS["FIXNUM_MIN"].should < 0 + RbConfig::LIMITS["FIXNUM_MAX"].should > 0 + end + + it "contains CHAR_MIN and CHAR_MAX" do + RbConfig::LIMITS["CHAR_MIN"].should <= 0 + RbConfig::LIMITS["CHAR_MAX"].should > 0 + end + + it "contains SHRT_MIN and SHRT_MAX" do + RbConfig::LIMITS["SHRT_MIN"].should == -32768 + RbConfig::LIMITS["SHRT_MAX"].should == 32767 + end + + it "contains INT_MIN and INT_MAX" do + RbConfig::LIMITS["INT_MIN"].should < 0 + RbConfig::LIMITS["INT_MAX"].should > 0 + end + + it "contains LONG_MIN and LONG_MAX" do + RbConfig::LIMITS["LONG_MIN"].should < 0 + RbConfig::LIMITS["LONG_MAX"].should > 0 + end + end +end diff --git a/spec/ruby/library/rbconfig/unicode_emoji_version_spec.rb b/spec/ruby/library/rbconfig/unicode_emoji_version_spec.rb new file mode 100644 index 0000000000..d3df8b7313 --- /dev/null +++ b/spec/ruby/library/rbconfig/unicode_emoji_version_spec.rb @@ -0,0 +1,22 @@ +require_relative '../../spec_helper' +require 'rbconfig' + +describe "RbConfig::CONFIG['UNICODE_EMOJI_VERSION']" do + ruby_version_is "2.6"..."2.6.2" do + it "is 11.0 for Ruby 2.6.0 and 2.6.1" do + RbConfig::CONFIG['UNICODE_EMOJI_VERSION'].should == "11.0" + end + end + + ruby_version_is "2.6.2"..."2.7" do + it "is 12.0 for Ruby 2.6.2+" do + RbConfig::CONFIG['UNICODE_EMOJI_VERSION'].should == "12.0" + end + end + + ruby_version_is "2.7" do + it "is 12.1 for Ruby 2.7" do + RbConfig::CONFIG['UNICODE_EMOJI_VERSION'].should == "12.1" + end + end +end diff --git a/spec/ruby/library/rbconfig/unicode_version_spec.rb b/spec/ruby/library/rbconfig/unicode_version_spec.rb new file mode 100644 index 0000000000..44216700c8 --- /dev/null +++ b/spec/ruby/library/rbconfig/unicode_version_spec.rb @@ -0,0 +1,34 @@ +require_relative '../../spec_helper' +require 'rbconfig' + +describe "RbConfig::CONFIG['UNICODE_VERSION']" do + ruby_version_is ""..."2.5" do + it "is 9.0.0 for Ruby 2.4" do + RbConfig::CONFIG['UNICODE_VERSION'].should == "9.0.0" + end + end + + ruby_version_is "2.5"..."2.6" do + it "is 10.0.0 for Ruby 2.5" do + RbConfig::CONFIG['UNICODE_VERSION'].should == "10.0.0" + end + end + + ruby_version_is "2.6"..."2.6.2" do + it "is 11.0.0 for Ruby 2.6.0 and 2.6.1" do + RbConfig::CONFIG['UNICODE_VERSION'].should == "11.0.0" + end + end + + ruby_version_is "2.6.2"..."2.6.3" do + it "is 12.0.0 for Ruby 2.6.2" do + RbConfig::CONFIG['UNICODE_VERSION'].should == "12.0.0" + end + end + + ruby_version_is "2.6.3" do + it "is 12.1.0 for Ruby 2.6.3+ and Ruby 2.7" do + RbConfig::CONFIG['UNICODE_VERSION'].should == "12.1.0" + end + end +end diff --git a/spec/ruby/library/scanf/io/scanf_spec.rb b/spec/ruby/library/scanf/io/scanf_spec.rb index 6a1fd66780..6a3e6d0d1a 100644 --- a/spec/ruby/library/scanf/io/scanf_spec.rb +++ b/spec/ruby/library/scanf/io/scanf_spec.rb @@ -6,8 +6,8 @@ ruby_version_is ''...'2.7' do describe "IO#scanf" do before :each do - @hw = File.open(fixture(__FILE__, 'helloworld.txt'), 'r') - @data = File.open(fixture(__FILE__, 'date.txt'), 'r') + @hw = File.open(fixture(__FILE__, 'helloworld.txt'), 'rb') + @data = File.open(fixture(__FILE__, 'date.txt'), 'rb') end after :each do diff --git a/spec/ruby/library/scanf/io/shared/block_scanf.rb b/spec/ruby/library/scanf/io/shared/block_scanf.rb index 2031f4c2b7..d938f43734 100644 --- a/spec/ruby/library/scanf/io/shared/block_scanf.rb +++ b/spec/ruby/library/scanf/io/shared/block_scanf.rb @@ -2,7 +2,7 @@ require 'scanf' describe :scanf_io_block_scanf, shared: true do before :each do - @data = File.open(fixture(__FILE__, 'date.txt'), 'r') + @data = File.open(fixture(__FILE__, 'date.txt'), 'rb') end after :each do diff --git a/spec/ruby/library/socket/basicsocket/read_nonblock_spec.rb b/spec/ruby/library/socket/basicsocket/read_nonblock_spec.rb new file mode 100644 index 0000000000..1823f3d75d --- /dev/null +++ b/spec/ruby/library/socket/basicsocket/read_nonblock_spec.rb @@ -0,0 +1,46 @@ +require_relative '../spec_helper' +require_relative '../fixtures/classes' + +ruby_version_is "2.5" do + describe "BasicSocket#read_nonblock" do + SocketSpecs.each_ip_protocol do |family, ip_address| + before :each do + @r = Socket.new(family, :DGRAM) + @w = Socket.new(family, :DGRAM) + + @r.bind(Socket.pack_sockaddr_in(0, ip_address)) + @w.send("aaa", 0, @r.getsockname) + end + + after :each do + @r.close unless @r.closed? + @w.close unless @w.closed? + end + + it "receives data after it's ready" do + IO.select([@r], nil, nil, 2) + @r.recv_nonblock(5).should == "aaa" + end + + platform_is :linux do + it 'does not set the IO in nonblock mode' do + require 'io/nonblock' + @r.nonblock?.should == false + IO.select([@r], nil, nil, 2) + @r.read_nonblock(3).should == "aaa" + @r.nonblock?.should == false + end + end + + platform_is_not :linux, :windows do + it 'sets the IO in nonblock mode' do + require 'io/nonblock' + @r.nonblock?.should == false + IO.select([@r], nil, nil, 2) + @r.read_nonblock(3).should == "aaa" + @r.nonblock?.should == true + end + end + end + end +end diff --git a/spec/ruby/library/socket/basicsocket/write_nonblock_spec.rb b/spec/ruby/library/socket/basicsocket/write_nonblock_spec.rb new file mode 100644 index 0000000000..f2e7366eb1 --- /dev/null +++ b/spec/ruby/library/socket/basicsocket/write_nonblock_spec.rb @@ -0,0 +1,45 @@ +require_relative '../spec_helper' +require_relative '../fixtures/classes' + +ruby_version_is "2.5" do + describe "BasicSocket#write_nonblock" do + SocketSpecs.each_ip_protocol do |family, ip_address| + before :each do + @r = Socket.new(family, :DGRAM) + @w = Socket.new(family, :DGRAM) + + @r.bind(Socket.pack_sockaddr_in(0, ip_address)) + @w.connect(@r.getsockname) + end + + after :each do + @r.close unless @r.closed? + @w.close unless @w.closed? + end + + it "sends data" do + @w.write_nonblock("aaa").should == 3 + IO.select([@r], nil, nil, 2) + @r.recv_nonblock(5).should == "aaa" + end + + platform_is :linux do + it 'does not set the IO in nonblock mode' do + require 'io/nonblock' + @w.nonblock?.should == false + @w.write_nonblock("aaa").should == 3 + @w.nonblock?.should == false + end + end + + platform_is_not :linux, :windows do + it 'sets the IO in nonblock mode' do + require 'io/nonblock' + @w.nonblock?.should == false + @w.write_nonblock("aaa").should == 3 + @w.nonblock?.should == true + end + end + end + end +end diff --git a/spec/ruby/library/socket/tcpserver/new_spec.rb b/spec/ruby/library/socket/tcpserver/new_spec.rb index d099f0175f..8d9696c9d8 100644 --- a/spec/ruby/library/socket/tcpserver/new_spec.rb +++ b/spec/ruby/library/socket/tcpserver/new_spec.rb @@ -48,6 +48,24 @@ describe "TCPServer.new" do addr[3].should == '0.0.0.0' end + it "binds to a port if the port is explicitly nil" do + @server = TCPServer.new('', nil) + addr = @server.addr + addr[0].should == 'AF_INET' + addr[1].should be_kind_of(Integer) + addr[2].should == '0.0.0.0' + addr[3].should == '0.0.0.0' + end + + it "binds to a port if the port is an empty string" do + @server = TCPServer.new('', '') + addr = @server.addr + addr[0].should == 'AF_INET' + addr[1].should be_kind_of(Integer) + addr[2].should == '0.0.0.0' + addr[3].should == '0.0.0.0' + end + it "coerces port to string, then determines port from that number or service name" do -> { TCPServer.new(SocketSpecs.hostname, Object.new) }.should raise_error(TypeError) @@ -62,6 +80,23 @@ describe "TCPServer.new" do # pick such a service port that will be able to reliably bind... end + it "has a single argument form and treats it as a port number" do + @server = TCPServer.new(0) + addr = @server.addr + addr[1].should be_kind_of(Integer) + end + + it "coerces port to a string when it is the only argument" do + -> { TCPServer.new(Object.new) }.should raise_error(TypeError) + + port = Object.new + port.should_receive(:to_str).and_return("0") + + @server = TCPServer.new(port) + addr = @server.addr + addr[1].should be_kind_of(Integer) + end + it "raises Errno::EADDRNOTAVAIL when the address is unknown" do -> { TCPServer.new("1.2.3.4", 0) }.should raise_error(Errno::EADDRNOTAVAIL) end diff --git a/spec/ruby/library/uri/select_spec.rb b/spec/ruby/library/uri/select_spec.rb index c2eb6f8733..839b68b3a1 100644 --- a/spec/ruby/library/uri/select_spec.rb +++ b/spec/ruby/library/uri/select_spec.rb @@ -15,12 +15,8 @@ describe "URI#select" do end it "raises an ArgumentError if a component is requested that isn't valid under the given scheme" do - [ - -> {URI("mailto:spam@mailinator.com").select(:path)}, - -> {URI("http://blog.blag.web").select(:typecode)}, - ].each do |select_lambda| - select_lambda.should raise_error(ArgumentError) - end + -> { URI("mailto:spam@mailinator.com").select(:path) }.should raise_error(ArgumentError) + -> { URI("http://blog.blag.web").select(:typecode) }.should raise_error(ArgumentError) end it "raises an ArgumentError if given strings rather than symbols" do diff --git a/spec/ruby/library/win32ole/win32ole_type/new_spec.rb b/spec/ruby/library/win32ole/win32ole_type/new_spec.rb index fab690c2dd..3c3aa1c390 100644 --- a/spec/ruby/library/win32ole/win32ole_type/new_spec.rb +++ b/spec/ruby/library/win32ole/win32ole_type/new_spec.rb @@ -12,15 +12,18 @@ platform_is :windows do it "raises TypeError if second argument is not a String" do -> { WIN32OLE_TYPE.new(1,2) }.should raise_error TypeError - -> { WIN32OLE_TYPE.new('Microsoft Shell Controls And Automation',2) }. - should raise_error TypeError + -> { + WIN32OLE_TYPE.new('Microsoft Shell Controls And Automation',2) + }.should raise_error TypeError end it "raise WIN32OLERuntimeError if OLE object specified is not found" do - -> { WIN32OLE_TYPE.new('Microsoft Shell Controls And Automation','foo') }. - should raise_error WIN32OLERuntimeError - -> { WIN32OLE_TYPE.new('Microsoft Shell Controls And Automation','Application') }. - should raise_error WIN32OLERuntimeError + -> { + WIN32OLE_TYPE.new('Microsoft Shell Controls And Automation','foo') + }.should raise_error WIN32OLERuntimeError + -> { + WIN32OLE_TYPE.new('Microsoft Shell Controls And Automation','Application') + }.should raise_error WIN32OLERuntimeError end it "creates WIN32OLE_TYPE object from name and valid type" do diff --git a/spec/ruby/library/zlib/deflate/append_spec.rb b/spec/ruby/library/zlib/deflate/append_spec.rb deleted file mode 100644 index e15f14f95f..0000000000 --- a/spec/ruby/library/zlib/deflate/append_spec.rb +++ /dev/null @@ -1 +0,0 @@ -require_relative '../../../spec_helper' diff --git a/spec/ruby/library/zlib/deflate/flush_spec.rb b/spec/ruby/library/zlib/deflate/flush_spec.rb deleted file mode 100644 index e15f14f95f..0000000000 --- a/spec/ruby/library/zlib/deflate/flush_spec.rb +++ /dev/null @@ -1 +0,0 @@ -require_relative '../../../spec_helper' diff --git a/spec/ruby/library/zlib/deflate_spec.rb b/spec/ruby/library/zlib/deflate_spec.rb index 01538dd4e6..6eeaa164c5 100644 --- a/spec/ruby/library/zlib/deflate_spec.rb +++ b/spec/ruby/library/zlib/deflate_spec.rb @@ -1,7 +1,7 @@ require_relative '../../spec_helper' require "zlib" -describe "Zlib#deflate" do +describe "Zlib.deflate" do it "deflates some data" do Zlib.deflate("1" * 10).should == [120, 156, 51, 52, 132, 1, 0, 10, 145, 1, 235].pack('C*') end diff --git a/spec/ruby/library/zlib/gunzip_spec.rb b/spec/ruby/library/zlib/gunzip_spec.rb new file mode 100644 index 0000000000..2417fed57c --- /dev/null +++ b/spec/ruby/library/zlib/gunzip_spec.rb @@ -0,0 +1,14 @@ +require_relative '../../spec_helper' +require 'zlib' + +describe "Zlib.gunzip" do + before :each do + @data = '12345abcde' + @zip = [31, 139, 8, 0, 44, 220, 209, 71, 0, 3, 51, 52, 50, 54, 49, 77, + 76, 74, 78, 73, 5, 0, 157, 5, 0, 36, 10, 0, 0, 0].pack('C*') + end + + it "decodes the given gzipped string" do + Zlib.gunzip(@zip).should == @data + end +end diff --git a/spec/ruby/library/zlib/gzip_spec.rb b/spec/ruby/library/zlib/gzip_spec.rb new file mode 100644 index 0000000000..35694264f0 --- /dev/null +++ b/spec/ruby/library/zlib/gzip_spec.rb @@ -0,0 +1,15 @@ +require_relative '../../spec_helper' +require 'zlib' + +describe "Zlib.gzip" do + before :each do + @data = '12345abcde' + @zip = [31, 139, 8, 0, 44, 220, 209, 71, 0, 3, 51, 52, 50, 54, 49, 77, + 76, 74, 78, 73, 5, 0, 157, 5, 0, 36, 10, 0, 0, 0].pack('C*') + end + + it "gzips the given string" do + # skip gzip header for now + Zlib.gzip(@data)[10..-1].should == @zip[10..-1] + end +end diff --git a/spec/ruby/library/zlib/gzipfile/crc_spec.rb b/spec/ruby/library/zlib/gzipfile/crc_spec.rb deleted file mode 100644 index e15f14f95f..0000000000 --- a/spec/ruby/library/zlib/gzipfile/crc_spec.rb +++ /dev/null @@ -1 +0,0 @@ -require_relative '../../../spec_helper' diff --git a/spec/ruby/library/zlib/gzipfile/finish_spec.rb b/spec/ruby/library/zlib/gzipfile/finish_spec.rb deleted file mode 100644 index e15f14f95f..0000000000 --- a/spec/ruby/library/zlib/gzipfile/finish_spec.rb +++ /dev/null @@ -1 +0,0 @@ -require_relative '../../../spec_helper' diff --git a/spec/ruby/library/zlib/gzipfile/level_spec.rb b/spec/ruby/library/zlib/gzipfile/level_spec.rb deleted file mode 100644 index e15f14f95f..0000000000 --- a/spec/ruby/library/zlib/gzipfile/level_spec.rb +++ /dev/null @@ -1 +0,0 @@ -require_relative '../../../spec_helper' diff --git a/spec/ruby/library/zlib/gzipfile/mtime_spec.rb b/spec/ruby/library/zlib/gzipfile/mtime_spec.rb deleted file mode 100644 index e15f14f95f..0000000000 --- a/spec/ruby/library/zlib/gzipfile/mtime_spec.rb +++ /dev/null @@ -1 +0,0 @@ -require_relative '../../../spec_helper' diff --git a/spec/ruby/library/zlib/gzipfile/os_code_spec.rb b/spec/ruby/library/zlib/gzipfile/os_code_spec.rb deleted file mode 100644 index e15f14f95f..0000000000 --- a/spec/ruby/library/zlib/gzipfile/os_code_spec.rb +++ /dev/null @@ -1 +0,0 @@ -require_relative '../../../spec_helper' diff --git a/spec/ruby/library/zlib/gzipfile/sync_spec.rb b/spec/ruby/library/zlib/gzipfile/sync_spec.rb deleted file mode 100644 index e15f14f95f..0000000000 --- a/spec/ruby/library/zlib/gzipfile/sync_spec.rb +++ /dev/null @@ -1 +0,0 @@ -require_relative '../../../spec_helper' diff --git a/spec/ruby/library/zlib/gzipfile/to_io_spec.rb b/spec/ruby/library/zlib/gzipfile/to_io_spec.rb deleted file mode 100644 index e15f14f95f..0000000000 --- a/spec/ruby/library/zlib/gzipfile/to_io_spec.rb +++ /dev/null @@ -1 +0,0 @@ -require_relative '../../../spec_helper' diff --git a/spec/ruby/library/zlib/gzipfile/wrap_spec.rb b/spec/ruby/library/zlib/gzipfile/wrap_spec.rb deleted file mode 100644 index e15f14f95f..0000000000 --- a/spec/ruby/library/zlib/gzipfile/wrap_spec.rb +++ /dev/null @@ -1 +0,0 @@ -require_relative '../../../spec_helper' diff --git a/spec/ruby/library/zlib/gzipreader/each_byte_spec.rb b/spec/ruby/library/zlib/gzipreader/each_byte_spec.rb index d2c43ecaa4..48821dc833 100644 --- a/spec/ruby/library/zlib/gzipreader/each_byte_spec.rb +++ b/spec/ruby/library/zlib/gzipreader/each_byte_spec.rb @@ -2,7 +2,7 @@ require_relative '../../../spec_helper' require 'stringio' require 'zlib' -describe "GzipReader#each_byte" do +describe "Zlib::GzipReader#each_byte" do before :each do @data = '12345abcde' diff --git a/spec/ruby/library/zlib/gzipreader/each_line_spec.rb b/spec/ruby/library/zlib/gzipreader/each_line_spec.rb index b576788e27..efaf27d6bb 100644 --- a/spec/ruby/library/zlib/gzipreader/each_line_spec.rb +++ b/spec/ruby/library/zlib/gzipreader/each_line_spec.rb @@ -1,5 +1,5 @@ require_relative 'shared/each' -describe "GzipReader#each_line" do +describe "Zlib::GzipReader#each_line" do it_behaves_like :gzipreader_each, :each_line end diff --git a/spec/ruby/library/zlib/gzipreader/each_spec.rb b/spec/ruby/library/zlib/gzipreader/each_spec.rb index f9b90be316..59aa63e52c 100644 --- a/spec/ruby/library/zlib/gzipreader/each_spec.rb +++ b/spec/ruby/library/zlib/gzipreader/each_spec.rb @@ -1,5 +1,5 @@ require_relative 'shared/each' -describe "GzipReader#each" do +describe "Zlib::GzipReader#each" do it_behaves_like :gzipreader_each, :each end diff --git a/spec/ruby/library/zlib/gzipreader/eof_spec.rb b/spec/ruby/library/zlib/gzipreader/eof_spec.rb index e33d8e3133..673220fdfd 100644 --- a/spec/ruby/library/zlib/gzipreader/eof_spec.rb +++ b/spec/ruby/library/zlib/gzipreader/eof_spec.rb @@ -2,8 +2,7 @@ require_relative '../../../spec_helper' require 'stringio' require 'zlib' -describe "GzipReader#eof?" do - +describe "Zlib::GzipReader#eof?" do before :each do @data = '{"a":1234}' @zip = [31, 139, 8, 0, 0, 0, 0, 0, 0, 3, 171, 86, 74, 84, 178, 50, @@ -49,8 +48,7 @@ describe "GzipReader#eof?" do gz.read(1).should == @data[i, 1] end gz.eof?.should be_true - gz.read().should == "" + gz.read.should == "" gz.eof?.should be_true end - end diff --git a/spec/ruby/library/zlib/gzipreader/getc_spec.rb b/spec/ruby/library/zlib/gzipreader/getc_spec.rb index 90b5ffe37a..e567231940 100644 --- a/spec/ruby/library/zlib/gzipreader/getc_spec.rb +++ b/spec/ruby/library/zlib/gzipreader/getc_spec.rb @@ -2,8 +2,7 @@ require_relative '../../../spec_helper' require 'stringio' require 'zlib' -describe "GzipReader#getc" do - +describe "Zlib::GzipReader#getc" do before :each do @data = '12345abcde' @zip = [31, 139, 8, 0, 44, 220, 209, 71, 0, 3, 51, 52, 50, 54, 49, 77, @@ -37,5 +36,4 @@ describe "GzipReader#getc" do gz.getc.should be_nil gz.pos.should == pos end - end diff --git a/spec/ruby/library/zlib/gzipreader/gets_spec.rb b/spec/ruby/library/zlib/gzipreader/gets_spec.rb index 8e4465e49c..d3a2e7d263 100644 --- a/spec/ruby/library/zlib/gzipreader/gets_spec.rb +++ b/spec/ruby/library/zlib/gzipreader/gets_spec.rb @@ -2,7 +2,7 @@ require_relative '../../../spec_helper' require 'zlib' require 'stringio' -describe 'GzipReader#gets' do +describe 'Zlib::GzipReader#gets' do describe 'with "" separator' do it 'reads paragraphs skipping newlines' do # gz contains "\n\n\n\n\n123\n45\n\n\n\n\nabc\nde\n\n\n\n\n" diff --git a/spec/ruby/library/zlib/gzipreader/lineno_spec.rb b/spec/ruby/library/zlib/gzipreader/lineno_spec.rb deleted file mode 100644 index e15f14f95f..0000000000 --- a/spec/ruby/library/zlib/gzipreader/lineno_spec.rb +++ /dev/null @@ -1 +0,0 @@ -require_relative '../../../spec_helper' diff --git a/spec/ruby/library/zlib/gzipreader/open_spec.rb b/spec/ruby/library/zlib/gzipreader/open_spec.rb deleted file mode 100644 index e15f14f95f..0000000000 --- a/spec/ruby/library/zlib/gzipreader/open_spec.rb +++ /dev/null @@ -1 +0,0 @@ -require_relative '../../../spec_helper' diff --git a/spec/ruby/library/zlib/gzipreader/pos_spec.rb b/spec/ruby/library/zlib/gzipreader/pos_spec.rb index df7c78ad8f..8586faec92 100644 --- a/spec/ruby/library/zlib/gzipreader/pos_spec.rb +++ b/spec/ruby/library/zlib/gzipreader/pos_spec.rb @@ -2,8 +2,7 @@ require_relative '../../../spec_helper' require 'stringio' require 'zlib' -describe "GzipReader#pos" do - +describe "Zlib::GzipReader#pos" do before :each do @data = '12345abcde' @zip = [31, 139, 8, 0, 44, 220, 209, 71, 0, 3, 51, 52, 50, 54, 49, 77, @@ -22,5 +21,4 @@ describe "GzipReader#pos" do gz.read gz.pos.should == @data.length end - end diff --git a/spec/ruby/library/zlib/gzipreader/read_spec.rb b/spec/ruby/library/zlib/gzipreader/read_spec.rb index a13f087fe9..b81954b5ce 100644 --- a/spec/ruby/library/zlib/gzipreader/read_spec.rb +++ b/spec/ruby/library/zlib/gzipreader/read_spec.rb @@ -2,8 +2,7 @@ require_relative '../../../spec_helper' require 'stringio' require 'zlib' -describe "GzipReader#read" do - +describe "Zlib::GzipReader#read" do before :each do @data = '12345abcde' @zip = [31, 139, 8, 0, 44, 220, 209, 71, 0, 3, 51, 52, 50, 54, 49, 77, @@ -64,5 +63,4 @@ describe "GzipReader#read" do gz.read(2**16).should be_nil end end - end diff --git a/spec/ruby/library/zlib/gzipreader/readchar_spec.rb b/spec/ruby/library/zlib/gzipreader/readchar_spec.rb deleted file mode 100644 index e15f14f95f..0000000000 --- a/spec/ruby/library/zlib/gzipreader/readchar_spec.rb +++ /dev/null @@ -1 +0,0 @@ -require_relative '../../../spec_helper' diff --git a/spec/ruby/library/zlib/gzipreader/readline_spec.rb b/spec/ruby/library/zlib/gzipreader/readline_spec.rb deleted file mode 100644 index e15f14f95f..0000000000 --- a/spec/ruby/library/zlib/gzipreader/readline_spec.rb +++ /dev/null @@ -1 +0,0 @@ -require_relative '../../../spec_helper' diff --git a/spec/ruby/library/zlib/gzipreader/readlines_spec.rb b/spec/ruby/library/zlib/gzipreader/readlines_spec.rb deleted file mode 100644 index e15f14f95f..0000000000 --- a/spec/ruby/library/zlib/gzipreader/readlines_spec.rb +++ /dev/null @@ -1 +0,0 @@ -require_relative '../../../spec_helper' diff --git a/spec/ruby/library/zlib/gzipreader/readpartial_spec.rb b/spec/ruby/library/zlib/gzipreader/readpartial_spec.rb index a367e5b856..559ce9f841 100644 --- a/spec/ruby/library/zlib/gzipreader/readpartial_spec.rb +++ b/spec/ruby/library/zlib/gzipreader/readpartial_spec.rb @@ -2,7 +2,7 @@ require_relative '../../../spec_helper' require 'stringio' require 'zlib' -describe 'GzipReader#readpartial' do +describe "Zlib::GzipReader#readpartial" do before :each do @data = '12345abcde' @zip = [31, 139, 8, 0, 44, 220, 209, 71, 0, 3, 51, 52, 50, 54, 49, 77, diff --git a/spec/ruby/library/zlib/gzipreader/rewind_spec.rb b/spec/ruby/library/zlib/gzipreader/rewind_spec.rb index 2e22458b43..b31abb6abf 100644 --- a/spec/ruby/library/zlib/gzipreader/rewind_spec.rb +++ b/spec/ruby/library/zlib/gzipreader/rewind_spec.rb @@ -2,8 +2,7 @@ require_relative '../../../spec_helper' require 'stringio' require 'zlib' -describe "GzipReader#rewind" do - +describe "Zlib::GzipReader#rewind" do before :each do @data = '12345abcde' @zip = [31, 139, 8, 0, 44, 220, 209, 71, 0, 3, 51, 52, 50, 54, 49, 77, diff --git a/spec/ruby/library/zlib/gzipreader/shared/each.rb b/spec/ruby/library/zlib/gzipreader/shared/each.rb index 11c15d8a66..71608e04ab 100644 --- a/spec/ruby/library/zlib/gzipreader/shared/each.rb +++ b/spec/ruby/library/zlib/gzipreader/shared/each.rb @@ -3,7 +3,6 @@ require 'stringio' require 'zlib' describe :gzipreader_each, shared: true do - before :each do @data = "firstline\nsecondline\n\nforthline" @zip = [31, 139, 8, 0, 244, 125, 128, 88, 2, 255, 75, 203, 44, 42, 46, 201, @@ -47,5 +46,4 @@ describe :gzipreader_each, shared: true do @gzreader.pos.should == i end end - end diff --git a/spec/ruby/library/zlib/gzipreader/tell_spec.rb b/spec/ruby/library/zlib/gzipreader/tell_spec.rb deleted file mode 100644 index e15f14f95f..0000000000 --- a/spec/ruby/library/zlib/gzipreader/tell_spec.rb +++ /dev/null @@ -1 +0,0 @@ -require_relative '../../../spec_helper' diff --git a/spec/ruby/library/zlib/gzipreader/ungetbyte_spec.rb b/spec/ruby/library/zlib/gzipreader/ungetbyte_spec.rb index 6fb6915f15..7fa0608f9f 100644 --- a/spec/ruby/library/zlib/gzipreader/ungetbyte_spec.rb +++ b/spec/ruby/library/zlib/gzipreader/ungetbyte_spec.rb @@ -2,7 +2,7 @@ require_relative '../../../spec_helper' require 'stringio' require 'zlib' -describe 'GzipReader#ungetbyte' do +describe "Zlib::GzipReader#ungetbyte" do before :each do @data = '12345abcde' @zip = [31, 139, 8, 0, 44, 220, 209, 71, 0, 3, 51, 52, 50, 54, 49, 77, diff --git a/spec/ruby/library/zlib/gzipreader/ungetc_spec.rb b/spec/ruby/library/zlib/gzipreader/ungetc_spec.rb index d19ec61610..34f2a1a2ca 100644 --- a/spec/ruby/library/zlib/gzipreader/ungetc_spec.rb +++ b/spec/ruby/library/zlib/gzipreader/ungetc_spec.rb @@ -2,7 +2,7 @@ require_relative '../../../spec_helper' require 'stringio' require 'zlib' -describe 'GzipReader#ungetc' do +describe "Zlib::GzipReader#ungetc" do before :each do @data = '12345abcde' @zip = [31, 139, 8, 0, 44, 220, 209, 71, 0, 3, 51, 52, 50, 54, 49, 77, diff --git a/spec/ruby/library/zlib/gzipreader/unused_spec.rb b/spec/ruby/library/zlib/gzipreader/unused_spec.rb deleted file mode 100644 index e15f14f95f..0000000000 --- a/spec/ruby/library/zlib/gzipreader/unused_spec.rb +++ /dev/null @@ -1 +0,0 @@ -require_relative '../../../spec_helper' diff --git a/spec/ruby/library/zlib/gzipwriter/comment_spec.rb b/spec/ruby/library/zlib/gzipwriter/comment_spec.rb deleted file mode 100644 index e15f14f95f..0000000000 --- a/spec/ruby/library/zlib/gzipwriter/comment_spec.rb +++ /dev/null @@ -1 +0,0 @@ -require_relative '../../../spec_helper' diff --git a/spec/ruby/library/zlib/gzipwriter/flush_spec.rb b/spec/ruby/library/zlib/gzipwriter/flush_spec.rb deleted file mode 100644 index e15f14f95f..0000000000 --- a/spec/ruby/library/zlib/gzipwriter/flush_spec.rb +++ /dev/null @@ -1 +0,0 @@ -require_relative '../../../spec_helper' diff --git a/spec/ruby/library/zlib/gzipwriter/new_spec.rb b/spec/ruby/library/zlib/gzipwriter/new_spec.rb deleted file mode 100644 index e15f14f95f..0000000000 --- a/spec/ruby/library/zlib/gzipwriter/new_spec.rb +++ /dev/null @@ -1 +0,0 @@ -require_relative '../../../spec_helper' diff --git a/spec/ruby/library/zlib/gzipwriter/open_spec.rb b/spec/ruby/library/zlib/gzipwriter/open_spec.rb deleted file mode 100644 index e15f14f95f..0000000000 --- a/spec/ruby/library/zlib/gzipwriter/open_spec.rb +++ /dev/null @@ -1 +0,0 @@ -require_relative '../../../spec_helper' diff --git a/spec/ruby/library/zlib/gzipwriter/orig_name_spec.rb b/spec/ruby/library/zlib/gzipwriter/orig_name_spec.rb deleted file mode 100644 index e15f14f95f..0000000000 --- a/spec/ruby/library/zlib/gzipwriter/orig_name_spec.rb +++ /dev/null @@ -1 +0,0 @@ -require_relative '../../../spec_helper' diff --git a/spec/ruby/library/zlib/gzipwriter/pos_spec.rb b/spec/ruby/library/zlib/gzipwriter/pos_spec.rb deleted file mode 100644 index e15f14f95f..0000000000 --- a/spec/ruby/library/zlib/gzipwriter/pos_spec.rb +++ /dev/null @@ -1 +0,0 @@ -require_relative '../../../spec_helper' diff --git a/spec/ruby/library/zlib/gzipwriter/print_spec.rb b/spec/ruby/library/zlib/gzipwriter/print_spec.rb deleted file mode 100644 index e15f14f95f..0000000000 --- a/spec/ruby/library/zlib/gzipwriter/print_spec.rb +++ /dev/null @@ -1 +0,0 @@ -require_relative '../../../spec_helper' diff --git a/spec/ruby/library/zlib/gzipwriter/printf_spec.rb b/spec/ruby/library/zlib/gzipwriter/printf_spec.rb deleted file mode 100644 index e15f14f95f..0000000000 --- a/spec/ruby/library/zlib/gzipwriter/printf_spec.rb +++ /dev/null @@ -1 +0,0 @@ -require_relative '../../../spec_helper' diff --git a/spec/ruby/library/zlib/gzipwriter/putc_spec.rb b/spec/ruby/library/zlib/gzipwriter/putc_spec.rb deleted file mode 100644 index e15f14f95f..0000000000 --- a/spec/ruby/library/zlib/gzipwriter/putc_spec.rb +++ /dev/null @@ -1 +0,0 @@ -require_relative '../../../spec_helper' diff --git a/spec/ruby/library/zlib/gzipwriter/puts_spec.rb b/spec/ruby/library/zlib/gzipwriter/puts_spec.rb deleted file mode 100644 index e15f14f95f..0000000000 --- a/spec/ruby/library/zlib/gzipwriter/puts_spec.rb +++ /dev/null @@ -1 +0,0 @@ -require_relative '../../../spec_helper' diff --git a/spec/ruby/library/zlib/gzipwriter/tell_spec.rb b/spec/ruby/library/zlib/gzipwriter/tell_spec.rb deleted file mode 100644 index e15f14f95f..0000000000 --- a/spec/ruby/library/zlib/gzipwriter/tell_spec.rb +++ /dev/null @@ -1 +0,0 @@ -require_relative '../../../spec_helper' diff --git a/spec/ruby/library/zlib/gzipwriter/write_spec.rb b/spec/ruby/library/zlib/gzipwriter/write_spec.rb index f694ce7cb7..522ae7f2aa 100644 --- a/spec/ruby/library/zlib/gzipwriter/write_spec.rb +++ b/spec/ruby/library/zlib/gzipwriter/write_spec.rb @@ -2,7 +2,7 @@ require_relative '../../../spec_helper' require 'stringio' require 'zlib' -describe "GzipWriter#write" do +describe "Zlib::GzipWriter#write" do before :each do @data = '12345abcde' @zip = [31, 139, 8, 0, 44, 220, 209, 71, 0, 3, 51, 52, 50, 54, 49, 77, diff --git a/spec/ruby/library/zlib/inflate/sync_point_spec.rb b/spec/ruby/library/zlib/inflate/sync_point_spec.rb deleted file mode 100644 index e15f14f95f..0000000000 --- a/spec/ruby/library/zlib/inflate/sync_point_spec.rb +++ /dev/null @@ -1 +0,0 @@ -require_relative '../../../spec_helper' diff --git a/spec/ruby/library/zlib/inflate/sync_spec.rb b/spec/ruby/library/zlib/inflate/sync_spec.rb deleted file mode 100644 index e15f14f95f..0000000000 --- a/spec/ruby/library/zlib/inflate/sync_spec.rb +++ /dev/null @@ -1 +0,0 @@ -require_relative '../../../spec_helper' diff --git a/spec/ruby/library/zlib/inflate_spec.rb b/spec/ruby/library/zlib/inflate_spec.rb index 393bea4f3c..42c8dc5fbe 100644 --- a/spec/ruby/library/zlib/inflate_spec.rb +++ b/spec/ruby/library/zlib/inflate_spec.rb @@ -1,7 +1,7 @@ require_relative '../../spec_helper' require "zlib" -describe "Zlib#inflate" do +describe "Zlib.inflate" do it "inflates some data" do Zlib.inflate([120, 156, 51, 52, 132, 1, 0, 10, 145, 1, 235].pack('C*')).should == "1" * 10 end diff --git a/spec/ruby/library/zlib/zlib_version_spec.rb b/spec/ruby/library/zlib/zlib_version_spec.rb index e724feaa39..f83dfae66d 100644 --- a/spec/ruby/library/zlib/zlib_version_spec.rb +++ b/spec/ruby/library/zlib/zlib_version_spec.rb @@ -1 +1,8 @@ require_relative '../../spec_helper' +require 'zlib' + +describe "Zlib.zlib_version" do + it "returns the version of the libz library" do + Zlib.zlib_version.should be_an_instance_of(String) + end +end diff --git a/spec/ruby/library/zlib/zstream/close_spec.rb b/spec/ruby/library/zlib/zstream/close_spec.rb deleted file mode 100644 index e15f14f95f..0000000000 --- a/spec/ruby/library/zlib/zstream/close_spec.rb +++ /dev/null @@ -1 +0,0 @@ -require_relative '../../../spec_helper' diff --git a/spec/ruby/library/zlib/zstream/closed_spec.rb b/spec/ruby/library/zlib/zstream/closed_spec.rb deleted file mode 100644 index e15f14f95f..0000000000 --- a/spec/ruby/library/zlib/zstream/closed_spec.rb +++ /dev/null @@ -1 +0,0 @@ -require_relative '../../../spec_helper' diff --git a/spec/ruby/library/zlib/zstream/end_spec.rb b/spec/ruby/library/zlib/zstream/end_spec.rb deleted file mode 100644 index e15f14f95f..0000000000 --- a/spec/ruby/library/zlib/zstream/end_spec.rb +++ /dev/null @@ -1 +0,0 @@ -require_relative '../../../spec_helper' diff --git a/spec/ruby/library/zlib/zstream/ended_spec.rb b/spec/ruby/library/zlib/zstream/ended_spec.rb deleted file mode 100644 index e15f14f95f..0000000000 --- a/spec/ruby/library/zlib/zstream/ended_spec.rb +++ /dev/null @@ -1 +0,0 @@ -require_relative '../../../spec_helper' diff --git a/spec/ruby/library/zlib/zstream/finish_spec.rb b/spec/ruby/library/zlib/zstream/finish_spec.rb deleted file mode 100644 index e15f14f95f..0000000000 --- a/spec/ruby/library/zlib/zstream/finish_spec.rb +++ /dev/null @@ -1 +0,0 @@ -require_relative '../../../spec_helper' diff --git a/spec/ruby/library/zlib/zstream/finished_spec.rb b/spec/ruby/library/zlib/zstream/finished_spec.rb deleted file mode 100644 index e15f14f95f..0000000000 --- a/spec/ruby/library/zlib/zstream/finished_spec.rb +++ /dev/null @@ -1 +0,0 @@ -require_relative '../../../spec_helper' diff --git a/spec/ruby/library/zlib/zstream/flush_next_in_spec.rb b/spec/ruby/library/zlib/zstream/flush_next_in_spec.rb deleted file mode 100644 index e15f14f95f..0000000000 --- a/spec/ruby/library/zlib/zstream/flush_next_in_spec.rb +++ /dev/null @@ -1 +0,0 @@ -require_relative '../../../spec_helper' diff --git a/spec/ruby/library/zlib/zstream/reset_spec.rb b/spec/ruby/library/zlib/zstream/reset_spec.rb deleted file mode 100644 index e15f14f95f..0000000000 --- a/spec/ruby/library/zlib/zstream/reset_spec.rb +++ /dev/null @@ -1 +0,0 @@ -require_relative '../../../spec_helper' diff --git a/spec/ruby/library/zlib/zstream/stream_end_spec.rb b/spec/ruby/library/zlib/zstream/stream_end_spec.rb deleted file mode 100644 index e15f14f95f..0000000000 --- a/spec/ruby/library/zlib/zstream/stream_end_spec.rb +++ /dev/null @@ -1 +0,0 @@ -require_relative '../../../spec_helper' diff --git a/spec/ruby/library/zlib/zstream/total_in_spec.rb b/spec/ruby/library/zlib/zstream/total_in_spec.rb deleted file mode 100644 index e15f14f95f..0000000000 --- a/spec/ruby/library/zlib/zstream/total_in_spec.rb +++ /dev/null @@ -1 +0,0 @@ -require_relative '../../../spec_helper' diff --git a/spec/ruby/library/zlib/zstream/total_out_spec.rb b/spec/ruby/library/zlib/zstream/total_out_spec.rb deleted file mode 100644 index e15f14f95f..0000000000 --- a/spec/ruby/library/zlib/zstream/total_out_spec.rb +++ /dev/null @@ -1 +0,0 @@ -require_relative '../../../spec_helper' diff --git a/spec/ruby/optional/capi/array_spec.rb b/spec/ruby/optional/capi/array_spec.rb index acd225e0e0..cf65bc19b6 100644 --- a/spec/ruby/optional/capi/array_spec.rb +++ b/spec/ruby/optional/capi/array_spec.rb @@ -249,6 +249,14 @@ describe "C-API Array function" do @s.RARRAY_PTR_assign(a, :set) a.should == [:set, :set, :set] end + + it "allows memcpying between arrays" do + a = [1, 2, 3] + b = [0, 0, 0] + @s.RARRAY_PTR_memcpy(a, b) + b.should == [1, 2, 3] + a.should == [1, 2, 3] # check a was not modified + end end describe "RARRAY_LEN" do diff --git a/spec/ruby/optional/capi/ext/array_spec.c b/spec/ruby/optional/capi/ext/array_spec.c index 69cb035e61..379ced318d 100644 --- a/spec/ruby/optional/capi/ext/array_spec.c +++ b/spec/ruby/optional/capi/ext/array_spec.c @@ -33,6 +33,19 @@ static VALUE array_spec_RARRAY_PTR_assign(VALUE self, VALUE array, VALUE value) return Qnil; } + +static VALUE array_spec_RARRAY_PTR_memcpy(VALUE self, VALUE array1, VALUE array2) { + VALUE *ptr1, *ptr2; + int size; + size = RARRAY_LEN(array1); + ptr1 = RARRAY_PTR(array1); + ptr2 = RARRAY_PTR(array2); + if (ptr1 != NULL && ptr2 != NULL) { + memcpy(ptr2, ptr1, size * sizeof(VALUE)); + } + return Qnil; +} + static VALUE array_spec_RARRAY_LEN(VALUE self, VALUE array) { return INT2FIX(RARRAY_LEN(array)); } @@ -229,6 +242,7 @@ void Init_array_spec(void) { rb_define_method(cls, "RARRAY_LEN", array_spec_RARRAY_LEN, 1); rb_define_method(cls, "RARRAY_PTR_iterate", array_spec_RARRAY_PTR_iterate, 1); rb_define_method(cls, "RARRAY_PTR_assign", array_spec_RARRAY_PTR_assign, 2); + rb_define_method(cls, "RARRAY_PTR_memcpy", array_spec_RARRAY_PTR_memcpy, 2); rb_define_method(cls, "RARRAY_AREF", array_spec_RARRAY_AREF, 2); rb_define_method(cls, "rb_ary_aref", array_spec_rb_ary_aref, -1); rb_define_method(cls, "rb_ary_clear", array_spec_rb_ary_clear, 1); diff --git a/spec/ruby/optional/capi/ext/gc_spec.c b/spec/ruby/optional/capi/ext/gc_spec.c index 0a76b9d40a..57b1f11faa 100644 --- a/spec/ruby/optional/capi/ext/gc_spec.c +++ b/spec/ruby/optional/capi/ext/gc_spec.c @@ -29,6 +29,10 @@ static VALUE gc_spec_rb_gc() { return Qnil; } +static VALUE gc_spec_rb_gc_adjust_memory_usage(VALUE self, VALUE diff) { + rb_gc_adjust_memory_usage(NUM2SSIZET(diff)); + return Qnil; +} void Init_gc_spec(void) { VALUE cls = rb_define_class("CApiGCSpecs", rb_cObject); @@ -43,6 +47,7 @@ void Init_gc_spec(void) { rb_define_method(cls, "rb_gc_enable", gc_spec_rb_gc_enable, 0); rb_define_method(cls, "rb_gc_disable", gc_spec_rb_gc_disable, 0); rb_define_method(cls, "rb_gc", gc_spec_rb_gc, 0); + rb_define_method(cls, "rb_gc_adjust_memory_usage", gc_spec_rb_gc_adjust_memory_usage, 1); } #ifdef __cplusplus diff --git a/spec/ruby/optional/capi/ext/kernel_spec.c b/spec/ruby/optional/capi/ext/kernel_spec.c index 63a2ff8432..e98ae35067 100644 --- a/spec/ruby/optional/capi/ext/kernel_spec.c +++ b/spec/ruby/optional/capi/ext/kernel_spec.c @@ -59,6 +59,14 @@ VALUE kernel_spec_rb_block_call_multi_arg(VALUE self, VALUE ary) { return rb_block_call(ary, rb_intern("inject"), 1, method_args, block_call_inject_multi_arg, Qnil); } +static VALUE return_extra_data(RB_BLOCK_CALL_FUNC_ARGLIST(yield_value, extra_data)) { + return extra_data; +} + +VALUE rb_block_call_extra_data(VALUE self, VALUE object) { + return rb_block_call(object, rb_intern("instance_exec"), 0, NULL, return_extra_data, object); +} + VALUE kernel_spec_rb_block_call_no_func(VALUE self, VALUE ary) { return rb_block_call(ary, rb_intern("map"), 0, NULL, NULL, Qnil); } @@ -304,6 +312,7 @@ void Init_kernel_spec(void) { rb_define_method(cls, "rb_block_call", kernel_spec_rb_block_call, 1); rb_define_method(cls, "rb_block_call_multi_arg", kernel_spec_rb_block_call_multi_arg, 1); rb_define_method(cls, "rb_block_call_no_func", kernel_spec_rb_block_call_no_func, 1); + rb_define_method(cls, "rb_block_call_extra_data", rb_block_call_extra_data, 1); rb_define_method(cls, "rb_block_proc", kernel_spec_rb_block_proc, 0); rb_define_method(cls, "rb_block_lambda", kernel_spec_rb_block_lambda, 0); rb_define_method(cls, "rb_frame_this_func_test", kernel_spec_rb_frame_this_func, 0); diff --git a/spec/ruby/optional/capi/ext/string_spec.c b/spec/ruby/optional/capi/ext/string_spec.c index 4976dc92c4..a44e437bba 100644 --- a/spec/ruby/optional/capi/ext/string_spec.c +++ b/spec/ruby/optional/capi/ext/string_spec.c @@ -411,6 +411,18 @@ static VALUE string_spec_rb_str_modify(VALUE self, VALUE str) { return str; } +static VALUE string_spec_rb_utf8_str_new_static(VALUE self) { + return rb_utf8_str_new_static("nokogiri", 8); +} + +static VALUE string_spec_rb_utf8_str_new(VALUE self) { + return rb_utf8_str_new("nokogiri", 8); +} + +static VALUE string_spec_rb_utf8_str_new_cstr(VALUE self) { + return rb_utf8_str_new_cstr("nokogiri"); +} + void Init_string_spec(void) { VALUE cls = rb_define_class("CApiStringSpecs", rb_cObject); rb_define_method(cls, "rb_cstr2inum", string_spec_rb_cstr2inum, 2); @@ -485,6 +497,9 @@ void Init_string_spec(void) { rb_define_method(cls, "rb_String", string_spec_rb_String, 1); rb_define_method(cls, "rb_string_value_cstr", string_spec_rb_string_value_cstr, 1); rb_define_method(cls, "rb_str_modify", string_spec_rb_str_modify, 1); + rb_define_method(cls, "rb_utf8_str_new_static", string_spec_rb_utf8_str_new_static, 0); + rb_define_method(cls, "rb_utf8_str_new", string_spec_rb_utf8_str_new, 0); + rb_define_method(cls, "rb_utf8_str_new_cstr", string_spec_rb_utf8_str_new_cstr, 0); } #ifdef __cplusplus diff --git a/spec/ruby/optional/capi/gc_spec.rb b/spec/ruby/optional/capi/gc_spec.rb index 1c34675f0d..46c03156e4 100644 --- a/spec/ruby/optional/capi/gc_spec.rb +++ b/spec/ruby/optional/capi/gc_spec.rb @@ -42,13 +42,20 @@ describe "CApiGCSpecs" do end describe "rb_gc" do - it "increases gc count" do gc_count = GC.count @f.rb_gc GC.count.should > gc_count end - end + describe "rb_gc_adjust_memory_usage" do + # Just check that it does not throw, as it seems hard to observe any effect + it "adjusts the amount of registered external memory" do + -> { + @f.rb_gc_adjust_memory_usage(8) + @f.rb_gc_adjust_memory_usage(-8) + }.should_not raise_error + end + end end diff --git a/spec/ruby/optional/capi/kernel_spec.rb b/spec/ruby/optional/capi/kernel_spec.rb index d123eb13ea..32cdd3f421 100644 --- a/spec/ruby/optional/capi/kernel_spec.rb +++ b/spec/ruby/optional/capi/kernel_spec.rb @@ -53,6 +53,11 @@ describe "C-API Kernel function" do i + 1 end.should == [2, 4, 6] end + + it "can pass extra data to the function" do + ary = [3] + @s.rb_block_call_extra_data(ary).should equal(ary) + end end describe "rb_frame_this_func" do diff --git a/spec/ruby/optional/capi/string_spec.rb b/spec/ruby/optional/capi/string_spec.rb index 4da31445fe..1ad35b9e8a 100644 --- a/spec/ruby/optional/capi/string_spec.rb +++ b/spec/ruby/optional/capi/string_spec.rb @@ -1007,4 +1007,28 @@ end str.should == "2345678".encode("UTF-32LE") end end + + describe "rb_utf8_str_new_static" do + it "returns a UTF-8 string of the correct characters and length" do + str = @s.rb_utf8_str_new_static + str.should == "nokogiri" + str.encoding.should == Encoding::UTF_8 + end + end + + describe "rb_utf8_str_new" do + it "returns a UTF-8 string of the correct characters and length" do + str = @s.rb_utf8_str_new + str.should == "nokogiri" + str.encoding.should == Encoding::UTF_8 + end + end + + describe "rb_utf8_str_new_cstr" do + it "returns a UTF-8 string of the correct characters and length" do + str = @s.rb_utf8_str_new_cstr + str.should == "nokogiri" + str.encoding.should == Encoding::UTF_8 + end + end end -- cgit v1.2.3