diff options
author | eregon <eregon@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2019-03-28 14:22:29 +0000 |
---|---|---|
committer | eregon <eregon@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2019-03-28 14:22:29 +0000 |
commit | a28aa80c739a1d169649a4da833ef48cfb3465b3 (patch) | |
tree | c2f6bb79c268bd60116b54319ea96f01bb7dda79 /spec/ruby/core | |
parent | 0f64776745ef31e626dec0d42b7fb2a5988397ec (diff) |
Update to ruby/spec@e81b3cd
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67361 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'spec/ruby/core')
-rw-r--r-- | spec/ruby/core/binding/fixtures/irb.rb | 3 | ||||
-rw-r--r-- | spec/ruby/core/binding/irb_spec.rb | 17 | ||||
-rw-r--r-- | spec/ruby/core/file/mtime_spec.rb | 2 | ||||
-rw-r--r-- | spec/ruby/core/float/to_s_spec.rb | 199 | ||||
-rw-r--r-- | spec/ruby/core/hash/shared/each.rb | 17 | ||||
-rw-r--r-- | spec/ruby/core/io/read_nonblock_spec.rb | 7 | ||||
-rw-r--r-- | spec/ruby/core/kernel/pp_spec.rb | 11 | ||||
-rw-r--r-- | spec/ruby/core/kernel/sleep_spec.rb | 10 | ||||
-rw-r--r-- | spec/ruby/core/method/parameters_spec.rb | 15 | ||||
-rw-r--r-- | spec/ruby/core/method/to_proc_spec.rb | 11 | ||||
-rw-r--r-- | spec/ruby/core/module/autoload_spec.rb | 92 | ||||
-rw-r--r-- | spec/ruby/core/module/const_set_spec.rb | 47 | ||||
-rw-r--r-- | spec/ruby/core/module/fixtures/autoload_overridden.rb | 3 | ||||
-rw-r--r-- | spec/ruby/core/string/end_with_spec.rb | 7 | ||||
-rw-r--r-- | spec/ruby/core/string/inspect_spec.rb | 8 | ||||
-rw-r--r-- | spec/ruby/core/thread/list_spec.rb | 19 | ||||
-rw-r--r-- | spec/ruby/core/tracepoint/eval_script_spec.rb | 26 | ||||
-rw-r--r-- | spec/ruby/core/tracepoint/instruction_sequence_spec.rb | 28 |
18 files changed, 465 insertions, 57 deletions
diff --git a/spec/ruby/core/binding/fixtures/irb.rb b/spec/ruby/core/binding/fixtures/irb.rb new file mode 100644 index 0000000000..5f305f2d5d --- /dev/null +++ b/spec/ruby/core/binding/fixtures/irb.rb @@ -0,0 +1,3 @@ +a = 10 + +binding.irb diff --git a/spec/ruby/core/binding/irb_spec.rb b/spec/ruby/core/binding/irb_spec.rb new file mode 100644 index 0000000000..dd3df0b28a --- /dev/null +++ b/spec/ruby/core/binding/irb_spec.rb @@ -0,0 +1,17 @@ +require_relative '../../spec_helper' + +ruby_version_is "2.5" do + describe "Binding#irb" do + it "creates an IRB session with the binding in scope" do + irb_fixture = fixture __FILE__, "irb.rb" + + out = IO.popen([*ruby_exe, irb_fixture], "r+") do |pipe| + pipe.puts "a ** 2" + pipe.puts "exit" + pipe.readlines.map(&:chomp) + end + + out[-3..-1].should == ["a ** 2", "100", "exit"] + end + end +end diff --git a/spec/ruby/core/file/mtime_spec.rb b/spec/ruby/core/file/mtime_spec.rb index d5769c0584..c5d854bb08 100644 --- a/spec/ruby/core/file/mtime_spec.rb +++ b/spec/ruby/core/file/mtime_spec.rb @@ -12,7 +12,7 @@ describe "File.mtime" do it "returns the modification Time of the file" do File.mtime(@filename).should be_kind_of(Time) - File.mtime(@filename).should be_close(@mtime, 2.0) + File.mtime(@filename).should be_close(@mtime, 60.0) end guard -> { platform_is :linux or (platform_is :windows and ruby_version_is '2.5') } do diff --git a/spec/ruby/core/float/to_s_spec.rb b/spec/ruby/core/float/to_s_spec.rb index 58a58549ed..127132b567 100644 --- a/spec/ruby/core/float/to_s_spec.rb +++ b/spec/ruby/core/float/to_s_spec.rb @@ -75,11 +75,11 @@ describe "Float#to_s" do -10000000000000000.0.to_s.should == "-1.0e+16" end - it "uses non-e format for a positive value with whole part having 17 significant figures" do + it "uses e format for a positive value with whole part having 17 significant figures" do 1000000000000000.0.to_s.should == "1.0e+15" end - it "uses non-e format for a negative value with whole part having 17 significant figures" do + it "uses e format for a negative value with whole part having 17 significant figures" do -1000000000000000.0.to_s.should == "-1.0e+15" end @@ -95,6 +95,201 @@ describe "Float#to_s" do it "outputs the minimal, unique form to represent the value" do 0.56.to_s.should == "0.56" end + + describe "matches" do + ruby_version_is "2.4" do # For unpack1 + it "random examples in all ranges" do + # 50.times do + # bytes = (0...8).map { rand(256) } + # string = bytes.pack('C8') + # float = string.unpack('D').first + # puts " #{bytes.pack('C8').inspect}.unpack1('D').to_s.should == #{float.to_s.inspect}" + # end + + "\x97\x15\xC1| \xF5\x19\xAD".unpack1('D').to_s.should == "-1.9910613439044092e-91" + "\xBF\xF0\x14\xAD\xDF\x17q\xD1".unpack1('D').to_s.should == "-2.075408637901046e+84" + "\xDF\xBD\xC0\x89\xDA\x1F&$".unpack1('D').to_s.should == "1.5219626883645564e-134" + "|0<?a\xFB\xBFG".unpack1('D').to_s.should == "4.251130678455814e+37" + "U\xEE*\xB7\xF1\xB8\xE7\x18".unpack1('D').to_s.should == "1.0648588700899858e-188" + "\x15Y\xD1J\x80/7\xD0".unpack1('D').to_s.should == "-2.6847034291392176e+78" + "\x1D\x1E\xD2\x9A3)\xF5q".unpack1('D').to_s.should == "8.818842365424256e+240" + "M\xD0C\xA3\x19-\xE3\xE5".unpack1('D').to_s.should == "-6.365746090981858e+182" + "\xAFf\xFE\xF0$\x85\x01L".unpack1('D').to_s.should == "1.374692728674642e+58" + "'N\xB7\x12\xE0\xC8t\t".unpack1('D').to_s.should == "4.1254080603298014e-263" + "\xAFn\xF2x\x85\xB5\x15j".unpack1('D').to_s.should == "1.0635019031720867e+203" + "nQ\x95\xFA\xD9\xE3\xC5)".unpack1('D').to_s.should == "1.8641386367625094e-107" + "\xC2\x9A\xB1|/\xCAJM".unpack1('D').to_s.should == "2.204135837758401e+64" + "q n\xD8\x86\xF2\xA8D".unpack1('D').to_s.should == "5.890531214599543e+22" + "dmR\xC6\xB3\xF3\x95G".unpack1('D').to_s.should == "7.294790578028111e+36" + "6I\x0E)?E\xB5\xE1".unpack1('D').to_s.should == "-4.7847061687992665e+162" + "\xCD\xE0\xBBy\x9F\xD8\xE89".unpack1('D').to_s.should == "9.800091365433584e-30" + "\xB8\x98TN\x98\xEE\xC1\xF9".unpack1('D').to_s.should == "-3.178740061599073e+278" + "\x8F_\xFF\x15\x1F2\x17B".unpack1('D').to_s.should == "24906286463.84332" + "\x94\x18V\xC5&\xE6\xEAi".unpack1('D').to_s.should == "1.6471900588998988e+202" + "\xECq\xB1\x01\ai\xBD,".unpack1('D').to_s.should == "3.5248469410018065e-93" + "\x9C\xC6\x13pG\xDAx\x9A".unpack1('D').to_s.should == "-3.743306318201459e-181" + "\xEA7,gJ\xEE\x8E*".unpack1('D').to_s.should == "1.0789044330549825e-103" + "1\xD3\xF5K\x8D\xEF\xA7\r".unpack1('D').to_s.should == "7.011009309284311e-243" + "o\xB3\x02\xAF\x9D\xFC\r\xF6".unpack1('D').to_s.should == "-4.610585875652112e+260" + "&:x\x15\xFC3P\x01".unpack1('D').to_s.should == "2.362770515774595e-302" + "\xE6<C\xB8\x90\xF2\xCF\x90".unpack1('D').to_s.should == "-1.0535871178808475e-227" + "\x9Al\aB6's}".unpack1('D').to_s.should == "1.957205609213647e+296" + "+\v\x16\xFD\x19\x0E\x9B\x06".unpack1('D').to_s.should == "7.631200870990123e-277" + "\xEC\xF8~\xDA\xE7Tf\x92".unpack1('D').to_s.should == "-4.942358450191624e-220" + "\xE0\xA0\xC9\x906\xBDcI".unpack1('D').to_s.should == "3.521575588133954e+45" + "\xBD\xFD\xC9\xFD\rp\x02\x0F".unpack1('D').to_s.should == "2.2651682962118346e-236" + "\xE9\xA8\xAD\xC4\xF6u\xF7\x19".unpack1('D').to_s.should == "1.3803378872547194e-183" + "\"f\xED9\x17\xF0\xF1!".unpack1('D').to_s.should == "3.591307506787987e-145" + "\xE6\xF2\xB6\x9CFl\xB3O".unpack1('D').to_s.should == "8.785250953340842e+75" + "g\xFD\xEA\r~x\xBA\x9D".unpack1('D').to_s.should == "-1.7955908504285607e-165" + "\xE2\x84J\xC7\x00\n/\x06".unpack1('D').to_s.should == "6.839790344291208e-279" + "s\xFB\xA58x\xF1\xA9\xD9".unpack1('D').to_s.should == "-8.574967051032431e+123" + "\xE2\x9D\xBE\xE2\x10k{\xFC".unpack1('D').to_s.should == "-4.2751876153404507e+291" + "!z \xB4i4\x8C5".unpack1('D').to_s.should == "9.423078517655126e-51" + "!_\xEAp- 7R".unpack1('D').to_s.should == "1.1500944673871687e+88" + "\x03\xAD=\\\xCB >\xBB".unpack1('D').to_s.should == "-2.4921382721208654e-23" + "\x94\x01\xB1\x87\x10\x9B#\x88".unpack1('D').to_s.should == "-1.8555672851958583e-269" + "\x90H\xFF\\S\x01)\x89".unpack1('D').to_s.should == "-1.5509713490195968e-264" + "HW@\x13\x85&=)".unpack1('D').to_s.should == "4.848496966571536e-110" + "\x14\xDB\\\x10\x93\x9C\xD66".unpack1('D').to_s.should == "1.5842813502410472e-44" + "\x9D8p>\xFF\x9B[\xF3".unpack1('D').to_s.should == "-4.826061446912647e+247" + "c\x9D}\t]\xF9pg".unpack1('D').to_s.should == "1.8907034486212682e+190" + "\xA51\xC9WJ\xB5a^".unpack1('D').to_s.should == "4.422435231445608e+146" + "\x8BL\x90\xCB\xEARf\f".unpack1('D').to_s.should == "6.235963569982745e-249" + end + + it "random examples in human ranges" do + # 50.times do + # formatted = '' + # rand(1..3).times do + # formatted << rand(10).to_s + # end + # formatted << '.' + # rand(1..9).times do + # formatted << rand(10).to_s + # end + # float = formatted.to_f + # string = [float].pack('D') + # puts " #{string.inspect}.unpack1('D').to_s.should == #{float.to_s.inspect}" + # end + + ";\x01M\x84\r\xF7M@".unpack1('D').to_s.should == "59.9301" + "\xAE\xD3HKe|\x8A@".unpack1('D').to_s.should == "847.54946" + "/\xDD$\x06\x81u8@".unpack1('D').to_s.should == "24.459" + "E\xD8\xF0\xF4JY\xF0?".unpack1('D').to_s.should == "1.0218" + "[\brP\xC2\xCC\x05@".unpack1('D').to_s.should == "2.72498" + "\xE6w\x9A\xCCx\xF6T@".unpack1('D').to_s.should == "83.851123" + "\xB4\xD4&\xC0C\xFD.@".unpack1('D').to_s.should == "15.494657521" + "\xCD\xCC\xCC\xCC\xCCLM@".unpack1('D').to_s.should == "58.6" + "\xA1\x84\x99\xB6\x7F\xE5\x13@".unpack1('D').to_s.should == "4.97412" + "\xD7\xA3p=\n\x9C\x80@".unpack1('D').to_s.should == "531.505" + "S\x96!\x8E\xF5\x0E\x8F@".unpack1('D').to_s.should == "993.8699" + "\xF1F\xE6\x91?\x18\xD7?".unpack1('D').to_s.should == "0.360855" + "=\n\xD7\xA3p=\x15@".unpack1('D').to_s.should == "5.31" + "\x90Ci\x147\xC74@".unpack1('D').to_s.should == "20.7781842" + "A\ft\xED\v\xE8\xB9?".unpack1('D').to_s.should == "0.101197" + "\x9A\x99\x99\x99\x999T@".unpack1('D').to_s.should == "80.9" + "\x00\x00\x00\x00\x00\x00\x1A@".unpack1('D').to_s.should == "6.5" + "\xD3J\xC6\xD6\x98\x8Es@".unpack1('D').to_s.should == "312.9123142" + "SQ\xE5I\fQ\x1E@".unpack1('D').to_s.should == "7.57914844" + "k]Q\xE7\xDDb\x1E@".unpack1('D').to_s.should == "7.59654962" + "\x1F\x85\xEBQ\xB8\xEAz@".unpack1('D').to_s.should == "430.67" + "\x00\x00\x00\x00\x00\x00\x14@".unpack1('D').to_s.should == "5.0" + "{\x14\xAEG\xE1\n}@".unpack1('D').to_s.should == "464.68" + "\x12\x83\xC0\xCA\xA1=V@".unpack1('D').to_s.should == "88.963" + "\x9Aw\x9C\xA2#y\e@".unpack1('D').to_s.should == "6.8683" + "(\x0F\v\xB5\xA6y\xFB?".unpack1('D').to_s.should == "1.7172" + "\xD5x\xE9&1H!@".unpack1('D').to_s.should == "8.641" + "w'Deh\x1Ab@".unpack1('D').to_s.should == "144.8252436" + ":X\xFF\xE70_\x04@".unpack1('D').to_s.should == "2.54648" + "E4\xB2\x12\x90\xCA\x1E@".unpack1('D').to_s.should == "7.69781522" + "fffff\xAA\x80@".unpack1('D').to_s.should == "533.3" + "\xCD\x92\x005\xB5p:@".unpack1('D').to_s.should == "26.440265" + "\xBE\x1D<nS\x7F\x19@".unpack1('D').to_s.should == "6.3743417" + "R\xB8\x1E\x85\xEBYb@".unpack1('D').to_s.should == "146.81" + "\x02\x87\xAB^\xD9\xC0\xF4?".unpack1('D').to_s.should == "1.2970823" + "\x00\x00\x00\x00\x00\x00\"@".unpack1('D').to_s.should == "9.0" + "Zd;\xDFO3\x84@".unpack1('D').to_s.should == "646.414" + "\x9A\x99\x99\x99\x99\x99\t@".unpack1('D').to_s.should == "3.2" + "\xCD#\x7F0\xF0\xE5i@".unpack1('D').to_s.should == "207.18557" + "\xBE\x9F\x1A/\xDD$\xF2?".unpack1('D').to_s.should == "1.134" + "\xEE|?5^\xBA\xF3?".unpack1('D').to_s.should == "1.233" + "\xB4\xB7\xFE\xD7\x05\x03i@".unpack1('D').to_s.should == "200.094463346" + "N\x95\xD6|\xE8HG@".unpack1('D').to_s.should == "46.56959496" + "Y\x868\xD6\xC5-!@".unpack1('D').to_s.should == "8.5894" + "myE\xED\a;\x12@".unpack1('D').to_s.should == "4.557647426" + "\xA7s\xEAo\xAE\x96B@".unpack1('D').to_s.should == "37.1771984" + "\x14\x7Fo.\x99\x11|@".unpack1('D').to_s.should == "449.0998978" + "\xB2\x9EZ}u\x89;@".unpack1('D').to_s.should == "27.536949" + "\xD7\xA3p=\nwY@".unpack1('D').to_s.should == "101.86" + "\xF3\xE6p\xAD\xF6\xC3x@".unpack1('D').to_s.should == "396.247724" + end + end + + it "random values from divisions" do + (1.0 / 7).to_s.should == "0.14285714285714285" + + # 50.times do + # a = rand(10) + # b = rand(10) + # c = rand(10) + # d = rand(10) + # expression = "#{a}.#{b} / #{c}.#{d}" + # puts " (#{expression}).to_s.should == #{eval(expression).to_s.inspect}" + # end + + (1.1 / 7.1).to_s.should == "0.15492957746478875" + (6.5 / 8.8).to_s.should == "0.7386363636363635" + (4.8 / 4.3).to_s.should == "1.1162790697674418" + (4.0 / 1.9).to_s.should == "2.1052631578947367" + (9.1 / 0.8).to_s.should == "11.374999999999998" + (5.3 / 7.5).to_s.should == "0.7066666666666667" + (2.8 / 1.8).to_s.should == "1.5555555555555554" + (2.1 / 2.5).to_s.should == "0.8400000000000001" + (3.5 / 6.0).to_s.should == "0.5833333333333334" + (4.6 / 0.3).to_s.should == "15.333333333333332" + (0.6 / 2.4).to_s.should == "0.25" + (1.3 / 9.1).to_s.should == "0.14285714285714288" + (0.3 / 5.0).to_s.should == "0.06" + (5.0 / 4.2).to_s.should == "1.1904761904761905" + (3.0 / 2.0).to_s.should == "1.5" + (6.3 / 2.0).to_s.should == "3.15" + (5.4 / 6.0).to_s.should == "0.9" + (9.6 / 8.1).to_s.should == "1.1851851851851851" + (8.7 / 1.6).to_s.should == "5.437499999999999" + (1.9 / 7.8).to_s.should == "0.24358974358974358" + (0.5 / 2.1).to_s.should == "0.23809523809523808" + (9.3 / 5.8).to_s.should == "1.6034482758620692" + (2.7 / 8.0).to_s.should == "0.3375" + (9.7 / 7.8).to_s.should == "1.2435897435897436" + (8.1 / 2.4).to_s.should == "3.375" + (7.7 / 2.7).to_s.should == "2.8518518518518516" + (7.9 / 1.7).to_s.should == "4.647058823529412" + (6.5 / 8.2).to_s.should == "0.7926829268292683" + (7.8 / 9.6).to_s.should == "0.8125" + (2.2 / 4.6).to_s.should == "0.47826086956521746" + (0.0 / 1.0).to_s.should == "0.0" + (8.3 / 2.9).to_s.should == "2.8620689655172415" + (3.1 / 6.1).to_s.should == "0.5081967213114754" + (2.8 / 7.8).to_s.should == "0.358974358974359" + (8.0 / 0.1).to_s.should == "80.0" + (1.7 / 6.4).to_s.should == "0.265625" + (1.8 / 5.4).to_s.should == "0.3333333333333333" + (8.0 / 5.8).to_s.should == "1.3793103448275863" + (5.2 / 4.1).to_s.should == "1.2682926829268295" + (9.8 / 5.8).to_s.should == "1.6896551724137934" + (5.4 / 9.5).to_s.should == "0.5684210526315789" + (8.4 / 4.9).to_s.should == "1.7142857142857142" + (1.7 / 3.5).to_s.should == "0.4857142857142857" + (1.2 / 5.1).to_s.should == "0.23529411764705882" + (1.4 / 2.0).to_s.should == "0.7" + (4.8 / 8.0).to_s.should == "0.6" + (9.0 / 2.5).to_s.should == "3.6" + (0.2 / 0.6).to_s.should == "0.33333333333333337" + (7.8 / 5.2).to_s.should == "1.5" + (9.5 / 5.5).to_s.should == "1.7272727272727273" + end + end end with_feature :encoding do diff --git a/spec/ruby/core/hash/shared/each.rb b/spec/ruby/core/hash/shared/each.rb index bf4c569cfc..1d89cfdd39 100644 --- a/spec/ruby/core/hash/shared/each.rb +++ b/spec/ruby/core/hash/shared/each.rb @@ -1,4 +1,6 @@ describe :hash_each, shared: true do + + # This is inconsistent with below, MRI checks the block arity in rb_hash_each_pair() it "yields a [[key, value]] Array for each pair to a block expecting |*args|" do all_args = [] { 1 => 2, 3 => 4 }.send(@method) { |*args| all_args << args } @@ -19,6 +21,21 @@ describe :hash_each, shared: true do ary.sort.should == ["a", "b", "c"] end + it "yields 2 values and not an Array of 2 elements" do + obj = Object.new + def obj.foo(key, value) + ScratchPad << key << value + end + + ScratchPad.record([]) + { "a" => 1 }.send(@method, &obj.method(:foo)) + ScratchPad.recorded.should == ["a", 1] + + ScratchPad.record([]) + { "a" => 1 }.send(@method, &-> key, value { ScratchPad << key << value }) + ScratchPad.recorded.should == ["a", 1] + end + it "uses the same order as keys() and values()" do h = { a: 1, b: 2, c: 3, d: 5 } keys = [] diff --git a/spec/ruby/core/io/read_nonblock_spec.rb b/spec/ruby/core/io/read_nonblock_spec.rb index 3c02f662f6..59f5064922 100644 --- a/spec/ruby/core/io/read_nonblock_spec.rb +++ b/spec/ruby/core/io/read_nonblock_spec.rb @@ -77,6 +77,13 @@ describe "IO#read_nonblock" do buffer.should == "1" end + it "returns the passed buffer" do + buffer = "" + @write.write("1") + output = @read.read_nonblock(1, buffer) + output.should equal(buffer) + end + it "raises IOError on closed stream" do lambda { IOSpecs.closed_io.read_nonblock(5) }.should raise_error(IOError) end diff --git a/spec/ruby/core/kernel/pp_spec.rb b/spec/ruby/core/kernel/pp_spec.rb new file mode 100644 index 0000000000..e19dc64caf --- /dev/null +++ b/spec/ruby/core/kernel/pp_spec.rb @@ -0,0 +1,11 @@ +require_relative '../../spec_helper' + +ruby_version_is "2.5" do + describe "Kernel#pp" do + it "lazily loads the 'pp' library and delegates the call to that library" do + # Run in child process to ensure 'pp' hasn't been loaded yet. + output = ruby_exe("pp [1, 2, 3]") + output.should == "[1, 2, 3]\n" + end + end +end diff --git a/spec/ruby/core/kernel/sleep_spec.rb b/spec/ruby/core/kernel/sleep_spec.rb index 489f4f8410..a510ae3dc1 100644 --- a/spec/ruby/core/kernel/sleep_spec.rb +++ b/spec/ruby/core/kernel/sleep_spec.rb @@ -6,16 +6,20 @@ describe "Kernel#sleep" do Kernel.should have_private_instance_method(:sleep) end + it "returns an Integer" do + sleep(0.001).should be_kind_of(Integer) + end + it "accepts a Float" do - sleep(0.1).should be_close(0, 2) + sleep(0.001).should >= 0 end it "accepts a Fixnum" do - sleep(0).should be_close(0, 2) + sleep(0).should >= 0 end it "accepts a Rational" do - sleep(Rational(1, 9)).should be_close(0, 2) + sleep(Rational(1, 999)).should >= 0 end it "raises an ArgumentError when passed a negative duration" do diff --git a/spec/ruby/core/method/parameters_spec.rb b/spec/ruby/core/method/parameters_spec.rb index d750f4c221..750abe13d0 100644 --- a/spec/ruby/core/method/parameters_spec.rb +++ b/spec/ruby/core/method/parameters_spec.rb @@ -241,4 +241,19 @@ describe "Method#parameters" do m = MethodSpecs::Methods.new m.method(:writer=).parameters.should == [[:req]] end + + it "returns [[:rest]] for core methods with variable-length argument lists" do + m = "foo" + + # match takes rest args + m.method(:match).parameters.should == [[:rest]] + + # [] takes 1 to 3 args + m.method(:[]).parameters.should == [[:rest]] + end + + it "returns [[:req]] for each parameter for core methods with fixed-length argument lists" do + m = "foo" + m.method(:+).parameters.should == [[:req]] + end end diff --git a/spec/ruby/core/method/to_proc_spec.rb b/spec/ruby/core/method/to_proc_spec.rb index 92bd64aaf1..29b7bec2b3 100644 --- a/spec/ruby/core/method/to_proc_spec.rb +++ b/spec/ruby/core/method/to_proc_spec.rb @@ -90,4 +90,15 @@ describe "Method#to_proc" do array.each(&obj) ScratchPad.recorded.should == [[1, 2]] end + + it "returns a proc that properly invokes module methods with super" do + m1 = Module.new { def foo(ary); ary << :m1; end; } + m2 = Module.new { def foo(ary = []); super(ary); ary << :m2; end; } + c2 = Class.new do + include m1 + include m2 + end + + c2.new.method(:foo).to_proc.call.should == %i[m1 m2] + end end diff --git a/spec/ruby/core/module/autoload_spec.rb b/spec/ruby/core/module/autoload_spec.rb index 224d5fd57b..918eb61764 100644 --- a/spec/ruby/core/module/autoload_spec.rb +++ b/spec/ruby/core/module/autoload_spec.rb @@ -16,17 +16,28 @@ end describe "Module#autoload" do before :all do @non_existent = fixture __FILE__, "no_autoload.rb" + + # Require RubyGems eagerly, to ensure #require is already the RubyGems + # version, before starting #autoload specs which snapshot #require, and + # could end up redefining #require as the original core Kernel#require. + begin + require "rubygems" + rescue LoadError + end end before :each do @loaded_features = $".dup - @frozen_module = Module.new.freeze ScratchPad.clear + @remove = [] end after :each do $".replace @loaded_features + @remove.each { |const| + ModuleSpecs::Autoload.send :remove_const, const + } end it "registers a file to load the first time the named constant is accessed" do @@ -39,16 +50,29 @@ describe "Module#autoload" do ModuleSpecs::Autoload.should have_constant(:B) end + it "can be overridden with a second autoload on the same constant" do + ModuleSpecs::Autoload.autoload :Overridden, @non_existent + @remove << :Overridden + ModuleSpecs::Autoload.autoload?(:Overridden).should == @non_existent + + path = fixture(__FILE__, "autoload_overridden.rb") + ModuleSpecs::Autoload.autoload :Overridden, path + ModuleSpecs::Autoload.autoload?(:Overridden).should == path + + ModuleSpecs::Autoload::Overridden.should == :overridden + end + it "loads the registered constant when it is accessed" do ModuleSpecs::Autoload.should_not have_constant(:X) ModuleSpecs::Autoload.autoload :X, fixture(__FILE__, "autoload_x.rb") + @remove << :X ModuleSpecs::Autoload::X.should == :x - ModuleSpecs::Autoload.send(:remove_const, :X) end it "loads the registered constant into a dynamically created class" do cls = Class.new { autoload :C, fixture(__FILE__, "autoload_c.rb") } ModuleSpecs::Autoload::DynClass = cls + @remove << :DynClass ScratchPad.recorded.should be_nil ModuleSpecs::Autoload::DynClass::C.new.loaded.should == :dynclass_c @@ -58,6 +82,7 @@ describe "Module#autoload" do it "loads the registered constant into a dynamically created module" do mod = Module.new { autoload :D, fixture(__FILE__, "autoload_d.rb") } ModuleSpecs::Autoload::DynModule = mod + @remove << :DynModule ScratchPad.recorded.should be_nil ModuleSpecs::Autoload::DynModule::D.new.loaded.should == :dynmodule_d @@ -95,6 +120,7 @@ describe "Module#autoload" do it "does not load the file when the constant is already set" do ModuleSpecs::Autoload.autoload :I, fixture(__FILE__, "autoload_i.rb") + @remove << :I ModuleSpecs::Autoload.const_set :I, 3 ModuleSpecs::Autoload::I.should == 3 ScratchPad.recorded.should be_nil @@ -116,6 +142,7 @@ describe "Module#autoload" do it "does not load the file if the file is manually required" do filename = fixture(__FILE__, "autoload_k.rb") ModuleSpecs::Autoload.autoload :KHash, filename + @remove << :KHash require filename ScratchPad.recorded.should == :loaded @@ -135,8 +162,8 @@ describe "Module#autoload" do ScratchPad.clear ModuleSpecs::Autoload.autoload :S, filename + @remove << :S ModuleSpecs::Autoload.autoload?(:S).should be_nil - ModuleSpecs::Autoload.send(:remove_const, :S) end it "retains the autoload even if the request to require fails" do @@ -182,11 +209,10 @@ describe "Module#autoload" do module ModuleSpecs::Autoload autoload :GoodParent, fixture(__FILE__, "autoload_nested.rb") end + @remove << :GoodParent defined?(ModuleSpecs::Autoload::GoodParent::Nested).should == 'constant' ScratchPad.recorded.should == :loaded - - ModuleSpecs::Autoload.send(:remove_const, :GoodParent) end it "returns nil when it fails to load an autoloaded parent when referencing a nested constant" do @@ -199,11 +225,12 @@ describe "Module#autoload" do end end - describe "the autoload is removed when the same file is required directly without autoload" do + describe "the autoload is triggered when the same file is required directly" do before :each do module ModuleSpecs::Autoload autoload :RequiredDirectly, fixture(__FILE__, "autoload_required_directly.rb") end + @remove << :RequiredDirectly @path = fixture(__FILE__, "autoload_required_directly.rb") @check = -> { [ @@ -214,10 +241,6 @@ describe "Module#autoload" do ScratchPad.record @check end - after :each do - ModuleSpecs::Autoload.send(:remove_const, :RequiredDirectly) - end - it "with a full path" do @check.call.should == ["constant", @path] require @path @@ -242,7 +265,7 @@ describe "Module#autoload" do nested_require = -> { result = nil ScratchPad.record -> { - result = [@check.call, Thread.new { @check.call }.value] + result = @check.call } require nested result @@ -251,24 +274,41 @@ describe "Module#autoload" do @check.call.should == ["constant", @path] require @path - cur, other = ScratchPad.recorded - cur.should == [nil, nil] - other.should == [nil, nil] + ScratchPad.recorded.should == [nil, nil] @check.call.should == ["constant", nil] end end + describe "after the autoload is triggered by require" do + before :each do + @path = tmp("autoload.rb") + end + + after :each do + rm_r @path + end + + it "the mapping feature to autoload is removed, and a new autoload with the same path is considered" do + ModuleSpecs::Autoload.autoload :RequireMapping1, @path + touch(@path) { |f| f.puts "ModuleSpecs::Autoload::RequireMapping1 = 1" } + ModuleSpecs::Autoload::RequireMapping1.should == 1 + + $LOADED_FEATURES.delete(@path) + ModuleSpecs::Autoload.autoload :RequireMapping2, @path[0...-3] + @remove << :RequireMapping2 + touch(@path) { |f| f.puts "ModuleSpecs::Autoload::RequireMapping2 = 2" } + ModuleSpecs::Autoload::RequireMapping2.should == 2 + end + end + describe "during the autoload before the constant is assigned" do before :each do @path = fixture(__FILE__, "autoload_during_autoload.rb") ModuleSpecs::Autoload.autoload :DuringAutoload, @path + @remove << :DuringAutoload raise unless ModuleSpecs::Autoload.autoload?(:DuringAutoload) == @path end - after :each do - ModuleSpecs::Autoload.send(:remove_const, :DuringAutoload) - end - def check_before_during_thread_after(&check) before = check.call to_autoload_thread, from_autoload_thread = Queue.new, Queue.new @@ -419,6 +459,7 @@ describe "Module#autoload" do X = get_value end end + @remove << :U ModuleSpecs::Autoload::U::V::X.should == :autoload_uvx end @@ -474,6 +515,7 @@ describe "Module#autoload" do end it "and fails when finding the undefined autoload constant in the the current scope when declared in current and defined in parent" do + @remove << :DeclaredInCurrentDefinedInParent module ModuleSpecs::Autoload ScratchPad.record -> { DeclaredInCurrentDefinedInParent = :declared_in_current_defined_in_parent @@ -494,6 +536,7 @@ describe "Module#autoload" do end it "in the included modules" do + @remove << :DefinedInIncludedModule module ModuleSpecs::Autoload ScratchPad.record -> { module DefinedInIncludedModule @@ -507,6 +550,7 @@ describe "Module#autoload" do end it "in the included modules of the superclass" do + @remove << :DefinedInSuperclassIncludedModule module ModuleSpecs::Autoload class LookupAfterAutoloadSuper end @@ -528,6 +572,7 @@ describe "Module#autoload" do end it "in the prepended modules" do + @remove << :DefinedInPrependedModule module ModuleSpecs::Autoload ScratchPad.record -> { module DefinedInPrependedModule @@ -567,10 +612,10 @@ describe "Module#autoload" do end end end + @remove << :W ModuleSpecs::Autoload::W::Y.should be_kind_of(Class) ScratchPad.recorded.should == :loaded - ModuleSpecs::Autoload::W.send(:remove_const, :Y) end it "does not call #require a second time and does not warn if already loading the same feature with #require" do @@ -611,6 +656,7 @@ describe "Module#autoload" do it "shares the autoload request across dup'ed copies of modules" do require fixture(__FILE__, "autoload_s.rb") + @remove << :S filename = fixture(__FILE__, "autoload_t.rb") mod1 = Module.new { autoload :T, filename } lambda { @@ -651,8 +697,9 @@ describe "Module#autoload" do describe "on a frozen module" do it "raises a #{frozen_error_class} before setting the name" do - lambda { @frozen_module.autoload :Foo, @non_existent }.should raise_error(frozen_error_class) - @frozen_module.should_not have_constant(:Foo) + frozen_module = Module.new.freeze + lambda { frozen_module.autoload :Foo, @non_existent }.should raise_error(frozen_error_class) + frozen_module.should_not have_constant(:Foo) end end @@ -675,6 +722,7 @@ describe "Module#autoload" do describe "(concurrently)" do it "blocks a second thread while a first is doing the autoload" do ModuleSpecs::Autoload.autoload :Concur, fixture(__FILE__, "autoload_concur.rb") + @remove << :Concur start = false @@ -717,8 +765,6 @@ describe "Module#autoload" do t2_val.should == t1_val t2_exc.should be_nil - - ModuleSpecs::Autoload.send(:remove_const, :Concur) end # https://bugs.ruby-lang.org/issues/10892 diff --git a/spec/ruby/core/module/const_set_spec.rb b/spec/ruby/core/module/const_set_spec.rb index f3c69cd3e0..25d22ffaba 100644 --- a/spec/ruby/core/module/const_set_spec.rb +++ b/spec/ruby/core/module/const_set_spec.rb @@ -72,6 +72,53 @@ describe "Module#const_set" do lambda { ConstantSpecs.const_set name, 1 }.should raise_error(TypeError) end + describe "when overwriting an existing constant" do + it "warns if the previous value was a normal value" do + mod = Module.new + mod.const_set :Foo, 42 + -> { + mod.const_set :Foo, 1 + }.should complain(/already initialized constant/) + mod.const_get(:Foo).should == 1 + end + + it "does not warn if the previous value was an autoload" do + mod = Module.new + mod.autoload :Foo, "not-existing" + -> { + mod.const_set :Foo, 1 + }.should_not complain + mod.const_get(:Foo).should == 1 + end + + it "does not warn if the previous value was undefined" do + path = fixture(__FILE__, "autoload_o.rb") + ScratchPad.record [] + mod = Module.new + + mod.autoload :Foo, path + -> { mod::Foo }.should raise_error(NameError) + + mod.should have_constant(:Foo) + mod.const_defined?(:Foo).should == false + mod.autoload?(:Foo).should == nil + + -> { + mod.const_set :Foo, 1 + }.should_not complain + mod.const_get(:Foo).should == 1 + end + + it "does not warn if the new value is an autoload" do + mod = Module.new + mod.const_set :Foo, 42 + -> { + mod.autoload :Foo, "not-existing" + }.should_not complain + mod.const_get(:Foo).should == 42 + end + end + describe "on a frozen module" do before :each do @frozen = Module.new.freeze diff --git a/spec/ruby/core/module/fixtures/autoload_overridden.rb b/spec/ruby/core/module/fixtures/autoload_overridden.rb new file mode 100644 index 0000000000..7062bcfabc --- /dev/null +++ b/spec/ruby/core/module/fixtures/autoload_overridden.rb @@ -0,0 +1,3 @@ +module ModuleSpecs::Autoload + Overridden = :overridden +end diff --git a/spec/ruby/core/string/end_with_spec.rb b/spec/ruby/core/string/end_with_spec.rb index 7268378a38..429888803c 100644 --- a/spec/ruby/core/string/end_with_spec.rb +++ b/spec/ruby/core/string/end_with_spec.rb @@ -47,4 +47,11 @@ describe "String#end_with?" do "céréale".end_with?("réale").should be_true end + it "raises an Encoding::CompatibilityError if the encodings are incompatible" do + pat = "ア".encode Encoding::EUC_JP + lambda do + "あれ".end_with?(pat) + end.should raise_error(Encoding::CompatibilityError) + end + end diff --git a/spec/ruby/core/string/inspect_spec.rb b/spec/ruby/core/string/inspect_spec.rb index 2cfcfe0e76..c1674c73c8 100644 --- a/spec/ruby/core/string/inspect_spec.rb +++ b/spec/ruby/core/string/inspect_spec.rb @@ -489,4 +489,12 @@ describe "String#inspect" do ].should be_computed_by(:inspect) end end + + describe "when the string's encoding is different than the result's encoding" do + describe "and the string's encoding is ASCII-compatible but the characters are non-ASCII" do + it "returns a string with the non-ASCII characters replaced by \\x notation" do + "\u{3042}".encode("EUC-JP").inspect.should == '"\\x{A4A2}"' + end + end + end end diff --git a/spec/ruby/core/thread/list_spec.rb b/spec/ruby/core/thread/list_spec.rb index bd56cb4c52..80dd15c6ca 100644 --- a/spec/ruby/core/thread/list_spec.rb +++ b/spec/ruby/core/thread/list_spec.rb @@ -35,8 +35,21 @@ describe "Thread.list" do t.join end end -end -describe "Thread.list" do - it "needs to be reviewed for spec completeness" + it "returns instances of Thread and not null or nil values" do + spawner = Thread.new do + Array.new(100) do + Thread.new {} + end + end + + while spawner.alive? + Thread.list.each { |th| + th.should be_kind_of(Thread) + } + end + + threads = spawner.value + threads.each(&:join) + end end diff --git a/spec/ruby/core/tracepoint/eval_script_spec.rb b/spec/ruby/core/tracepoint/eval_script_spec.rb index 8a153156d1..1d8e425a9a 100644 --- a/spec/ruby/core/tracepoint/eval_script_spec.rb +++ b/spec/ruby/core/tracepoint/eval_script_spec.rb @@ -2,21 +2,23 @@ require_relative '../../spec_helper' require_relative 'fixtures/classes' ruby_version_is "2.6" do - describe "#eval_script" do - ScratchPad.record [] + describe "TracePoint#eval_script" do + it "is the evald source code" do + ScratchPad.record [] - script = <<-CODE - def foo - p :hello + script = <<-CODE + def foo + p :hello + end + CODE + + TracePoint.new(:script_compiled) do |e| + ScratchPad << e.eval_script + end.enable do + eval script end - CODE - TracePoint.new(:script_compiled) do |e| - ScratchPad << e.eval_script - end.enable do - eval script + ScratchPad.recorded.should == [script] end - - ScratchPad.recorded.should == [script] end end diff --git a/spec/ruby/core/tracepoint/instruction_sequence_spec.rb b/spec/ruby/core/tracepoint/instruction_sequence_spec.rb index 50a9cd5722..3e3b73cccc 100644 --- a/spec/ruby/core/tracepoint/instruction_sequence_spec.rb +++ b/spec/ruby/core/tracepoint/instruction_sequence_spec.rb @@ -2,22 +2,24 @@ require_relative '../../spec_helper' require_relative 'fixtures/classes' ruby_version_is "2.6" do - describe "#instruction_sequence" do - ScratchPad.record [] + describe "TracePoint#instruction_sequence" do + it "is an instruction sequence" do + ScratchPad.record [] - script = <<-CODE - def foo - p :hello + script = <<-CODE + def foo + p :hello + end + CODE + + TracePoint.new(:script_compiled) do |e| + ScratchPad << e.instruction_sequence + end.enable do + eval script end - CODE - TracePoint.new(:script_compiled) do |e| - ScratchPad << e.instruction_sequence - end.enable do - eval script + ScratchPad.recorded.size.should == 1 + ScratchPad.recorded[0].class.should == RubyVM::InstructionSequence end - - ScratchPad.recorded.size.should == 1 - ScratchPad.recorded[0].class.should == RubyVM::InstructionSequence end end |