diff options
author | eregon <eregon@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2017-09-20 20:18:52 +0000 |
---|---|---|
committer | eregon <eregon@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2017-09-20 20:18:52 +0000 |
commit | 1d15d5f08032acf1b7bceacbb450d617ff6e0931 (patch) | |
tree | a3785a79899302bc149e4a6e72f624ac27dc1f10 /spec/ruby/language/fixtures | |
parent | 75bfc6440d595bf339007f4fb280fd4d743e89c1 (diff) | |
download | ruby-1d15d5f08032acf1b7bceacbb450d617ff6e0931.tar.gz |
Move spec/rubyspec to spec/ruby for consistency
* Other ruby implementations use the spec/ruby directory.
[Misc #13792] [ruby-core:82287]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59979 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'spec/ruby/language/fixtures')
41 files changed, 2366 insertions, 0 deletions
diff --git a/spec/ruby/language/fixtures/argv_encoding.rb b/spec/ruby/language/fixtures/argv_encoding.rb new file mode 100644 index 0000000000..8192b2d9a0 --- /dev/null +++ b/spec/ruby/language/fixtures/argv_encoding.rb @@ -0,0 +1 @@ +p ARGV.map { |a| a.encoding.name } diff --git a/spec/ruby/language/fixtures/array.rb b/spec/ruby/language/fixtures/array.rb new file mode 100644 index 0000000000..4d8ce74ed6 --- /dev/null +++ b/spec/ruby/language/fixtures/array.rb @@ -0,0 +1,11 @@ +module ArraySpec + class Splat + def unpack_3args(a, b, c) + [a, b, c] + end + + def unpack_4args(a, b, c, d) + [a, b, c, d] + end + end +end diff --git a/spec/ruby/language/fixtures/block.rb b/spec/ruby/language/fixtures/block.rb new file mode 100644 index 0000000000..9848d18776 --- /dev/null +++ b/spec/ruby/language/fixtures/block.rb @@ -0,0 +1,57 @@ +module BlockSpecs + class Yielder + def z + yield + end + + def m(*a) + yield(*a) + end + + def s(a) + yield(a) + end + + def r(a) + yield(*a) + end + end + + # TODO: rewrite all specs that use Yield to use Yielder + + class Yield + def splat(*args) + yield(*args) + end + + def two_args + yield 1, 2 + end + + def two_arg_array + yield [1, 2] + end + + def yield_splat_inside_block + [1, 2].send(:each_with_index) {|*args| yield(*args)} + end + + def yield_this(obj) + yield obj + end + end + + class OverwriteBlockVariable + def initialize + @y = Yielder.new + end + + def method_missing(method, *args, &block) + self.class.send :define_method, method do |*a, &b| + @y.send method, *a, &b + end + + send method, *args, &block + end + end +end diff --git a/spec/ruby/language/fixtures/break.rb b/spec/ruby/language/fixtures/break.rb new file mode 100644 index 0000000000..50e7fcf5d9 --- /dev/null +++ b/spec/ruby/language/fixtures/break.rb @@ -0,0 +1,263 @@ +module BreakSpecs + class Driver + def initialize(ensures=false) + @ensures = ensures + end + + def note(value) + ScratchPad << value + end + end + + class Block < Driver + def break_nil + note :a + note yielding { + note :b + break + note :c + } + note :d + end + + def break_value + note :a + note yielding { + note :b + break :break + note :c + } + note :d + end + + def yielding + note :aa + note yield + note :bb + end + + def create_block + note :za + b = capture_block do + note :zb + break :break + note :zc + end + note :zd + b + end + + def capture_block(&b) + note :xa + b + end + + def break_in_method_captured + note :a + create_block.call + note :b + end + + def break_in_yield_captured + note :a + yielding(&create_block) + note :b + end + + def break_in_method + note :a + b = capture_block { + note :b + break :break + note :c + } + note :d + note b.call + note :e + end + + def call_method(b) + note :aa + note b.call + note :bb + end + + def break_in_nested_method + note :a + b = capture_block { + note :b + break :break + note :c + } + note :cc + note call_method(b) + note :d + end + + def break_in_yielding_method + note :a + b = capture_block { + note :b + break :break + note :c + } + note :cc + note yielding(&b) + note :d + end + + def method(v) + yield v + end + + def invoke_yield_in_while + looping = true + while looping + note :aa + yield + note :bb + looping = false + end + note :should_not_reach_here + end + + def break_in_block_in_while + invoke_yield_in_while do + note :break + break :value + note :c + end + end + end + + class Lambda < Driver + # Cases for the invocation of the scope defining the lambda still active + # on the call stack when the lambda is invoked. + def break_in_defining_scope(value=true) + note :a + note lambda { + note :b + if value + break :break + else + break + end + note :c + }.call + note :d + end + + def break_in_nested_scope + note :a + l = lambda do + note :b + break :break + note :c + end + note :d + + invoke_lambda l + + note :e + end + + def invoke_lambda(l) + note :aa + note l.call + note :bb + end + + def break_in_nested_scope_yield + note :a + l = lambda do + note :b + break :break + note :c + end + note :d + + invoke_yield(&l) + + note :e + end + + def note_invoke_yield + note :aa + note yield + note :bb + end + + def break_in_nested_scope_block + note :a + l = lambda do + note :b + break :break + note :c + end + note :d + + invoke_lambda_block l + + note :e + end + + def invoke_yield + note :aaa + yield + note :bbb + end + + def invoke_lambda_block(b) + note :aa + invoke_yield do + note :bb + + note b.call + + note :cc + end + note :dd + end + + # Cases for the invocation of the scope defining the lambda NOT still + # active on the call stack when the lambda is invoked. + def create_lambda + note :la + l = lambda do + note :lb + break :break + note :lc + end + note :ld + l + end + + def break_in_method + note :a + + note create_lambda.call + + note :b + end + + def break_in_block_in_method + note :a + invoke_yield do + note :b + + note create_lambda.call + + note :c + end + note :d + end + + def break_in_method_yield + note :a + + invoke_yield(&create_lambda) + + note :b + end + end +end diff --git a/spec/ruby/language/fixtures/break_lambda_toplevel.rb b/spec/ruby/language/fixtures/break_lambda_toplevel.rb new file mode 100644 index 0000000000..05af1d3fdc --- /dev/null +++ b/spec/ruby/language/fixtures/break_lambda_toplevel.rb @@ -0,0 +1,9 @@ +print "a," + +print lambda { + print "b," + break "break," + print "c," +}.call + +puts "d" diff --git a/spec/ruby/language/fixtures/break_lambda_toplevel_block.rb b/spec/ruby/language/fixtures/break_lambda_toplevel_block.rb new file mode 100644 index 0000000000..a35cb8a8a1 --- /dev/null +++ b/spec/ruby/language/fixtures/break_lambda_toplevel_block.rb @@ -0,0 +1,23 @@ +print "a," + +l = lambda { + print "b," + break "break," + print "c," +} + +def a(l) + print "d," + b { l.call } + print "e," +end + +def b + print "f," + print yield + print "g," +end + +a(l) + +puts "h" diff --git a/spec/ruby/language/fixtures/break_lambda_toplevel_method.rb b/spec/ruby/language/fixtures/break_lambda_toplevel_method.rb new file mode 100644 index 0000000000..200040d614 --- /dev/null +++ b/spec/ruby/language/fixtures/break_lambda_toplevel_method.rb @@ -0,0 +1,17 @@ +print "a," + +l = lambda { + print "b," + break "break," + print "c," +} + +def a(l) + print "d," + print l.call + print "e," +end + +a(l) + +puts "f" diff --git a/spec/ruby/language/fixtures/classes.rb b/spec/ruby/language/fixtures/classes.rb new file mode 100644 index 0000000000..eb239e1e29 --- /dev/null +++ b/spec/ruby/language/fixtures/classes.rb @@ -0,0 +1,31 @@ +module LanguageSpecs + # Regexp support + + def self.paired_delimiters + [%w[( )], %w[{ }], %w[< >], ["[", "]"]] + end + + def self.non_paired_delimiters + %w[~ ! # $ % ^ & * _ + ` - = " ' , . ? / | \\] + end + + def self.blanks + " \t" + end + + def self.white_spaces + return blanks + "\f\n\r\v" + end + + def self.non_alphanum_non_space + '~!@#$%^&*()+-\|{}[]:";\'<>?,./' + end + + def self.punctuations + ",.?" # TODO - Need to fill in the full list + end + + def self.get_regexp_with_substitution o + /#{o}/o + end +end diff --git a/spec/ruby/language/fixtures/coding_us_ascii.rb b/spec/ruby/language/fixtures/coding_us_ascii.rb new file mode 100644 index 0000000000..7df66109d7 --- /dev/null +++ b/spec/ruby/language/fixtures/coding_us_ascii.rb @@ -0,0 +1,11 @@ +# encoding: us-ascii + +module CodingUS_ASCII + def self.encoding + __ENCODING__ + end + + def self.string_literal + "string literal" + end +end diff --git a/spec/ruby/language/fixtures/coding_utf_8.rb b/spec/ruby/language/fixtures/coding_utf_8.rb new file mode 100644 index 0000000000..3d8e1d9a34 --- /dev/null +++ b/spec/ruby/language/fixtures/coding_utf_8.rb @@ -0,0 +1,11 @@ +# encoding: utf-8 + +module CodingUTF_8 + def self.encoding + __ENCODING__ + end + + def self.string_literal + "string literal" + end +end diff --git a/spec/ruby/language/fixtures/constant_visibility.rb b/spec/ruby/language/fixtures/constant_visibility.rb new file mode 100644 index 0000000000..022554430e --- /dev/null +++ b/spec/ruby/language/fixtures/constant_visibility.rb @@ -0,0 +1,98 @@ +module ConstantVisibility + module ModuleContainer + module PrivateModule + end + private_constant :PrivateModule + + class PrivateClass + end + private_constant :PrivateClass + end + + class ClassContainer + module PrivateModule + end + private_constant :PrivateModule + + class PrivateClass + end + private_constant :PrivateClass + end + + module PrivConstModule + PRIVATE_CONSTANT_MODULE = true + private_constant :PRIVATE_CONSTANT_MODULE + + def self.private_constant_from_self + PRIVATE_CONSTANT_MODULE + end + + def self.defined_from_self + defined? PRIVATE_CONSTANT_MODULE + end + + module Nested + def self.private_constant_from_scope + PRIVATE_CONSTANT_MODULE + end + + def self.defined_from_scope + defined? PRIVATE_CONSTANT_MODULE + end + end + end + + class PrivConstClass + PRIVATE_CONSTANT_CLASS = true + private_constant :PRIVATE_CONSTANT_CLASS + + def self.private_constant_from_self + PRIVATE_CONSTANT_CLASS + end + + def self.defined_from_self + defined? PRIVATE_CONSTANT_CLASS + end + + module Nested + def self.private_constant_from_scope + PRIVATE_CONSTANT_CLASS + end + + def self.defined_from_scope + defined? PRIVATE_CONSTANT_CLASS + end + end + end + + class PrivConstModuleChild + include PrivConstModule + + def private_constant_from_include + PRIVATE_CONSTANT_MODULE + end + + def defined_from_include + defined? PRIVATE_CONSTANT_MODULE + end + end + + class PrivConstClassChild < PrivConstClass + def private_constant_from_subclass + PRIVATE_CONSTANT_CLASS + end + + def defined_from_subclass + defined? PRIVATE_CONSTANT_CLASS + end + end + + def self.reset_private_constants + Object.send :private_constant, :PRIVATE_CONSTANT_IN_OBJECT + end +end + +class Object + PRIVATE_CONSTANT_IN_OBJECT = true + private_constant :PRIVATE_CONSTANT_IN_OBJECT +end diff --git a/spec/ruby/language/fixtures/constants_sclass.rb b/spec/ruby/language/fixtures/constants_sclass.rb new file mode 100644 index 0000000000..21dc4081e2 --- /dev/null +++ b/spec/ruby/language/fixtures/constants_sclass.rb @@ -0,0 +1,54 @@ +module ConstantSpecs + + CS_SINGLETON1 = Object.new + class << CS_SINGLETON1 + CONST = 1 + def foo + CONST + end + end + + CS_SINGLETON2 = [Object.new, Object.new] + 2.times do |i| + obj = CS_SINGLETON2[i] + $spec_i = i + class << obj + CONST = ($spec_i + 1) + def foo + CONST + end + end + end + + CS_SINGLETON3 = [Object.new, Object.new] + 2.times do |i| + obj = CS_SINGLETON3[i] + class << obj + class X + # creates <singleton class::X> + end + + def x + X + end + end + end + + CS_SINGLETON4 = [Object.new, Object.new] + CS_SINGLETON4_CLASSES = [] + 2.times do |i| + obj = CS_SINGLETON4[i] + $spec_i = i + class << obj + class X + CS_SINGLETON4_CLASSES << self + CONST = ($spec_i + 1) + + def foo + CONST + end + end + end + end + +end diff --git a/spec/ruby/language/fixtures/def.rb b/spec/ruby/language/fixtures/def.rb new file mode 100644 index 0000000000..81bfce73d0 --- /dev/null +++ b/spec/ruby/language/fixtures/def.rb @@ -0,0 +1,8 @@ +def some_toplevel_method +end + +public +def public_toplevel_method +end + +private diff --git a/spec/ruby/language/fixtures/defined.rb b/spec/ruby/language/fixtures/defined.rb new file mode 100644 index 0000000000..d26e553c4b --- /dev/null +++ b/spec/ruby/language/fixtures/defined.rb @@ -0,0 +1,298 @@ +module DefinedSpecs + self::SelfScoped = 42 + + def self.side_effects + ScratchPad.record :defined_specs_side_effects + end + + def self.fixnum_method + ScratchPad.record :defined_specs_fixnum_method + 42 + end + + def self.exception_method + ScratchPad.record :defined_specs_exception + raise "defined? specs exception method" + end + + def self.defined_method + DefinedSpecs + end + + class Basic + A = 42 + + def defined_method + DefinedSpecs + end + + def a_defined_method + end + + def protected_method + end + protected :protected_method + + def private_method + end + private :private_method + + def private_method_defined + defined? private_method + end + + def private_predicate? + end + private :private_predicate? + + def private_predicate_defined + defined? private_predicate? + end + + def local_variable_defined + x = 2 + defined? x + end + + def local_variable_defined_nil + x = nil + defined? x + end + + def instance_variable_undefined + defined? @instance_variable_undefined + end + + def instance_variable_read + value = @instance_variable_read + defined? @instance_variable_read + end + + def instance_variable_defined + @instance_variable_defined = 1 + defined? @instance_variable_defined + end + + def instance_variable_defined_nil + @instance_variable_defined_nil = nil + defined? @instance_variable_defined_nil + end + + def global_variable_undefined + defined? $defined_specs_global_variable_undefined + end + + def global_variable_read + suppress_warning do + value = $defined_specs_global_variable_read + end + defined? $defined_specs_global_variable_read + end + + def global_variable_defined + $defined_specs_global_variable_defined = 1 + defined? $defined_specs_global_variable_defined + end + + def class_variable_undefined + defined? @@class_variable_undefined + end + + def class_variable_defined + @@class_variable_defined = 1 + defined? @@class_variable_defined + end + + def yield_defined_method + defined? yield + end + + def yield_defined_parameter_method(&block) + defined? yield + end + + def no_yield_block + yield_defined_method + end + + def no_yield_block_parameter + yield_defined_parameter_method + end + + def yield_block + yield_defined_method { 42 } + end + + def yield_block_parameter + yield_defined_parameter_method { 42 } + end + end + + module Mixin + MixinConstant = 42 + + def defined_super + defined? super() + end + end + + class Parent + ParentConstant = 42 + + def defined_super; end + end + + class Child < Parent + include Mixin + + A = 42 + + def self.parent_constant_defined + defined? self::ParentConstant + end + + def self.module_defined + defined? Mixin + end + + def self.module_constant_defined + defined? MixinConstant + end + + def defined_super + super + end + end + + class Superclass + def yield_method + yield + end + + def method_no_args + end + + def method_args + end + + def method_block_no_args + end + + def method_block_args + end + + def define_method_no_args + end + + def define_method_args + end + + def define_method_block_no_args + end + + def define_method_block_args + end + end + + class Super < Superclass + def no_super_method_no_args + defined? super + end + + def no_super_method_args + defined? super() + end + + def method_no_args + defined? super + end + + def method_args + defined? super() + end + + def no_super_method_block_no_args + yield_method { defined? super } + end + + def no_super_method_block_args + yield_method { defined? super() } + end + + def method_block_no_args + yield_method { defined? super } + end + + def method_block_args + yield_method { defined? super() } + end + + define_method(:no_super_define_method_no_args) { defined? super } + define_method(:no_super_define_method_args) { defined? super() } + define_method(:define_method_no_args) { defined? super } + define_method(:define_method_args) { defined? super() } + + define_method(:no_super_define_method_block_no_args) do + yield_method { defined? super } + end + + define_method(:no_super_define_method_block_args) do + yield_method { defined? super() } + end + + define_method(:define_method_block_no_args) do + yield_method { defined? super } + end + + define_method(:define_method_block_args) do + yield_method { defined? super() } + end + end + + class ClassWithMethod + def test + end + end + + class ClassUndefiningMethod < ClassWithMethod + undef :test + end + + class ClassWithoutMethod < ClassUndefiningMethod + # If an undefined method overridden in descendants + # define?(super) should return nil + def test + defined?(super) + end + end + + module IntermediateModule1 + def method_no_args + end + end + + module IntermediateModule2 + def method_no_args + defined?(super) + end + end + + class SuperWithIntermediateModules + include IntermediateModule1 + include IntermediateModule2 + + def method_no_args + super + end + end +end + +class Object + def defined_specs_method + DefinedSpecs + end + + def defined_specs_receiver + DefinedSpecs::Basic.new + end +end diff --git a/spec/ruby/language/fixtures/dollar_zero.rb b/spec/ruby/language/fixtures/dollar_zero.rb new file mode 100644 index 0000000000..683bce8d4e --- /dev/null +++ b/spec/ruby/language/fixtures/dollar_zero.rb @@ -0,0 +1,6 @@ +puts $0 +puts __FILE__ + +if $0 == __FILE__ + print "OK" +end diff --git a/spec/ruby/language/fixtures/ensure.rb b/spec/ruby/language/fixtures/ensure.rb new file mode 100644 index 0000000000..0dad7d8401 --- /dev/null +++ b/spec/ruby/language/fixtures/ensure.rb @@ -0,0 +1,72 @@ +module EnsureSpec + class Container + attr_reader :executed + + def initialize + @executed = [] + end + + def raise_in_method_with_ensure + @executed << :method + raise "An Exception" + ensure + @executed << :ensure + end + + def raise_and_rescue_in_method_with_ensure + @executed << :method + raise "An Exception" + rescue + @executed << :rescue + ensure + @executed << :ensure + end + + def throw_in_method_with_ensure + @executed << :method + throw(:symbol) + ensure + @executed << :ensure + end + + def implicit_return_in_method_with_ensure + :method + ensure + :ensure + end + + def explicit_return_in_method_with_ensure + return :method + ensure + return :ensure + end + end +end + +module EnsureSpec + + class Test + + def initialize + @values = [] + end + + attr_reader :values + + def call_block + begin + @values << :start + yield + ensure + @values << :end + end + end + + def do_test + call_block do + @values << :in_block + return :did_test + end + end + end +end diff --git a/spec/ruby/language/fixtures/file.rb b/spec/ruby/language/fixtures/file.rb new file mode 100644 index 0000000000..7b862cfe1a --- /dev/null +++ b/spec/ruby/language/fixtures/file.rb @@ -0,0 +1 @@ +ScratchPad.record __FILE__ diff --git a/spec/ruby/language/fixtures/freeze_magic_comment_across_files.rb b/spec/ruby/language/fixtures/freeze_magic_comment_across_files.rb new file mode 100644 index 0000000000..3aed2f29b6 --- /dev/null +++ b/spec/ruby/language/fixtures/freeze_magic_comment_across_files.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +require_relative 'freeze_magic_comment_required' + +p "abc".object_id == $second_literal_id diff --git a/spec/ruby/language/fixtures/freeze_magic_comment_across_files_diff_enc.rb b/spec/ruby/language/fixtures/freeze_magic_comment_across_files_diff_enc.rb new file mode 100644 index 0000000000..53ef959970 --- /dev/null +++ b/spec/ruby/language/fixtures/freeze_magic_comment_across_files_diff_enc.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +require_relative 'freeze_magic_comment_required_diff_enc' + +p "abc".object_id != $second_literal_id diff --git a/spec/ruby/language/fixtures/freeze_magic_comment_across_files_no_comment.rb b/spec/ruby/language/fixtures/freeze_magic_comment_across_files_no_comment.rb new file mode 100644 index 0000000000..fc6cd5bf82 --- /dev/null +++ b/spec/ruby/language/fixtures/freeze_magic_comment_across_files_no_comment.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +require_relative 'freeze_magic_comment_required_no_comment' + +p "abc".object_id != $second_literal_id diff --git a/spec/ruby/language/fixtures/freeze_magic_comment_one_literal.rb b/spec/ruby/language/fixtures/freeze_magic_comment_one_literal.rb new file mode 100644 index 0000000000..d35905b332 --- /dev/null +++ b/spec/ruby/language/fixtures/freeze_magic_comment_one_literal.rb @@ -0,0 +1,4 @@ +# frozen_string_literal: true + +ids = Array.new(2) { "abc".object_id } +p ids.first == ids.last diff --git a/spec/ruby/language/fixtures/freeze_magic_comment_required.rb b/spec/ruby/language/fixtures/freeze_magic_comment_required.rb new file mode 100644 index 0000000000..a4ff4459b1 --- /dev/null +++ b/spec/ruby/language/fixtures/freeze_magic_comment_required.rb @@ -0,0 +1,3 @@ +# frozen_string_literal: true + +$second_literal_id = "abc".object_id diff --git a/spec/ruby/language/fixtures/freeze_magic_comment_required_diff_enc.rb b/spec/ruby/language/fixtures/freeze_magic_comment_required_diff_enc.rb Binary files differnew file mode 100644 index 0000000000..d0558a2251 --- /dev/null +++ b/spec/ruby/language/fixtures/freeze_magic_comment_required_diff_enc.rb diff --git a/spec/ruby/language/fixtures/freeze_magic_comment_required_no_comment.rb b/spec/ruby/language/fixtures/freeze_magic_comment_required_no_comment.rb new file mode 100644 index 0000000000..e09232a5f4 --- /dev/null +++ b/spec/ruby/language/fixtures/freeze_magic_comment_required_no_comment.rb @@ -0,0 +1 @@ +$second_literal_id = "abc".object_id diff --git a/spec/ruby/language/fixtures/freeze_magic_comment_two_literals.rb b/spec/ruby/language/fixtures/freeze_magic_comment_two_literals.rb new file mode 100644 index 0000000000..a4d655ad02 --- /dev/null +++ b/spec/ruby/language/fixtures/freeze_magic_comment_two_literals.rb @@ -0,0 +1,3 @@ +# frozen_string_literal: true + +p "abc".object_id == "abc".object_id diff --git a/spec/ruby/language/fixtures/hash_strings_ascii8bit.rb b/spec/ruby/language/fixtures/hash_strings_ascii8bit.rb new file mode 100644 index 0000000000..4ac11b9930 --- /dev/null +++ b/spec/ruby/language/fixtures/hash_strings_ascii8bit.rb @@ -0,0 +1,7 @@ +# encoding: ascii-8bit + +module HashStringsASCII8BIT + def self.literal_hash + {"foo" => "bar"} + end +end diff --git a/spec/ruby/language/fixtures/hash_strings_usascii.rb b/spec/ruby/language/fixtures/hash_strings_usascii.rb new file mode 100644 index 0000000000..18cfef7c8c --- /dev/null +++ b/spec/ruby/language/fixtures/hash_strings_usascii.rb @@ -0,0 +1,7 @@ +# encoding: us-ascii + +module HashStringsUSASCII + def self.literal_hash + {"foo" => "bar"} + end +end diff --git a/spec/ruby/language/fixtures/hash_strings_utf8.rb b/spec/ruby/language/fixtures/hash_strings_utf8.rb new file mode 100644 index 0000000000..7928090282 --- /dev/null +++ b/spec/ruby/language/fixtures/hash_strings_utf8.rb @@ -0,0 +1,7 @@ +# encoding: utf-8 + +module HashStringsUTF8 + def self.literal_hash + {"foo" => "bar"} + end +end diff --git a/spec/ruby/language/fixtures/match_operators.rb b/spec/ruby/language/fixtures/match_operators.rb new file mode 100644 index 0000000000..f04c54d723 --- /dev/null +++ b/spec/ruby/language/fixtures/match_operators.rb @@ -0,0 +1,9 @@ +class OperatorImplementor + def =~(val) + return val + end + + def !~(val) + return val + end +end diff --git a/spec/ruby/language/fixtures/metaclass.rb b/spec/ruby/language/fixtures/metaclass.rb new file mode 100644 index 0000000000..a1990b9225 --- /dev/null +++ b/spec/ruby/language/fixtures/metaclass.rb @@ -0,0 +1,34 @@ +module MetaClassSpecs + + def self.metaclass_of obj + class << obj + self + end + end + + class A + def self.cheese + 'edam' + end + end + + class B < A + def self.cheese + 'stilton' + end + end + + class C + class << self + class << self + def ham + 'iberico' + end + end + end + end + + class D < C; end + +end + diff --git a/spec/ruby/language/fixtures/module.rb b/spec/ruby/language/fixtures/module.rb new file mode 100644 index 0000000000..33d323846e --- /dev/null +++ b/spec/ruby/language/fixtures/module.rb @@ -0,0 +1,24 @@ +module ModuleSpecs + module Modules + class Klass + end + + A = "Module" + B = 1 + C = nil + D = true + E = false + end + + module Anonymous + end + + module IncludedInObject + module IncludedModuleSpecs + end + end +end + +class Object + include ModuleSpecs::IncludedInObject +end diff --git a/spec/ruby/language/fixtures/next.rb b/spec/ruby/language/fixtures/next.rb new file mode 100644 index 0000000000..fbca842334 --- /dev/null +++ b/spec/ruby/language/fixtures/next.rb @@ -0,0 +1,134 @@ +class NextSpecs + def self.yielding_method(expected) + yield.should == expected + :method_return_value + end + + def self.yielding + yield + end + + # The methods below are defined to spec the behavior of the next statement + # while specifically isolating whether the statement is in an Iter block or + # not. In a normal spec example, the code is always nested inside a block. + # Rather than rely on that implicit context in this case, the context is + # made explicit because of the interaction of next in a loop nested inside + # an Iter block. + def self.while_next(arg) + x = true + while x + begin + ScratchPad << :begin + x = false + if arg + next 42 + else + next + end + ensure + ScratchPad << :ensure + end + end + end + + def self.while_within_iter(arg) + yielding do + x = true + while x + begin + ScratchPad << :begin + x = false + if arg + next 42 + else + next + end + ensure + ScratchPad << :ensure + end + end + end + end + + def self.until_next(arg) + x = false + until x + begin + ScratchPad << :begin + x = true + if arg + next 42 + else + next + end + ensure + ScratchPad << :ensure + end + end + end + + def self.until_within_iter(arg) + yielding do + x = false + until x + begin + ScratchPad << :begin + x = true + if arg + next 42 + else + next + end + ensure + ScratchPad << :ensure + end + end + end + end + + def self.loop_next(arg) + x = 1 + loop do + break if x == 2 + + begin + ScratchPad << :begin + x += 1 + if arg + next 42 + else + next + end + ensure + ScratchPad << :ensure + end + end + end + + def self.loop_within_iter(arg) + yielding do + x = 1 + loop do + break if x == 2 + + begin + ScratchPad << :begin + x += 1 + if arg + next 42 + else + next + end + ensure + ScratchPad << :ensure + end + end + end + end + + class Block + def method(v) + yield v + end + end +end diff --git a/spec/ruby/language/fixtures/precedence.rb b/spec/ruby/language/fixtures/precedence.rb new file mode 100644 index 0000000000..d2295c755b --- /dev/null +++ b/spec/ruby/language/fixtures/precedence.rb @@ -0,0 +1,16 @@ +module PrecedenceSpecs + class NonUnaryOpTest + def add_num(arg) + [1].collect { |i| arg + i +1 } + end + def sub_num(arg) + [1].collect { |i| arg + i -1 } + end + def add_str + %w[1].collect { |i| i +'1' } + end + def add_var + [1].collect { |i| i +i } + end + end +end diff --git a/spec/ruby/language/fixtures/private.rb b/spec/ruby/language/fixtures/private.rb new file mode 100644 index 0000000000..96f73cea3f --- /dev/null +++ b/spec/ruby/language/fixtures/private.rb @@ -0,0 +1,59 @@ +module Private + class A + def foo + "foo" + end + + private + def bar + "bar" + end + end + + class B + def foo + "foo" + end + + private + + def self.public_defs_method; 0; end + + class C + def baz + "baz" + end + end + + class << self + def public_class_method1; 1; end + private + def private_class_method1; 1; end + end + + def bar + "bar" + end + end + + module D + private + def foo + "foo" + end + end + + class E + include D + end + + class G + def foo + "foo" + end + end + + class H < A + private :foo + end +end diff --git a/spec/ruby/language/fixtures/rescue.rb b/spec/ruby/language/fixtures/rescue.rb new file mode 100644 index 0000000000..3fa5df1eb5 --- /dev/null +++ b/spec/ruby/language/fixtures/rescue.rb @@ -0,0 +1,63 @@ +module RescueSpecs + def self.begin_else(raise_exception) + begin + ScratchPad << :one + raise "an error occurred" if raise_exception + rescue + ScratchPad << :rescue_ran + :rescue_val + else + ScratchPad << :else_ran + :val + end + end + + def self.begin_else_ensure(raise_exception) + begin + ScratchPad << :one + raise "an error occurred" if raise_exception + rescue + ScratchPad << :rescue_ran + :rescue_val + else + ScratchPad << :else_ran + :val + ensure + ScratchPad << :ensure_ran + :ensure_val + end + end + + def self.begin_else_return(raise_exception) + begin + ScratchPad << :one + raise "an error occurred" if raise_exception + rescue + ScratchPad << :rescue_ran + :rescue_val + else + ScratchPad << :else_ran + :val + end + ScratchPad << :outside_begin + :return_val + end + + def self.begin_else_return_ensure(raise_exception) + begin + ScratchPad << :one + raise "an error occurred" if raise_exception + rescue + ScratchPad << :rescue_ran + :rescue_val + else + ScratchPad << :else_ran + :val + ensure + ScratchPad << :ensure_ran + :ensure_val + end + ScratchPad << :outside_begin + :return_val + end +end diff --git a/spec/ruby/language/fixtures/return.rb b/spec/ruby/language/fixtures/return.rb new file mode 100644 index 0000000000..0414c356e8 --- /dev/null +++ b/spec/ruby/language/fixtures/return.rb @@ -0,0 +1,139 @@ +module ReturnSpecs + class Blocks + def yielding_method + yield + ScratchPad.record :after_yield + end + + def enclosing_method + yielding_method do + ScratchPad.record :before_return + return :return_value + ScratchPad.record :after_return + end + + ScratchPad.record :after_call + end + end + + class NestedCalls < Blocks + def invoking_method(&b) + yielding_method(&b) + ScratchPad.record :after_invoke + end + + def enclosing_method + invoking_method do + ScratchPad.record :before_return + return :return_value + ScratchPad.record :after_return + end + ScratchPad.record :after_invoke + end + end + + class NestedBlocks < Blocks + def enclosing_method + yielding_method do + yielding_method do + ScratchPad.record :before_return + return :return_value + ScratchPad.record :after_return + end + ScratchPad.record :after_invoke1 + end + ScratchPad.record :after_invoke2 + end + end + + class SavedInnerBlock + def add(&b) + @block = b + end + + def outer + yield + @block.call + end + + def inner + yield + end + + def start + outer do + inner do + add do + ScratchPad.record :before_return + return :return_value + end + end + end + + ScratchPad.record :bottom_of_start + + return false + end + end + + class ThroughDefineMethod + lamb = proc { |x| x.call } + define_method :foo, lamb + + def mp(&b); b; end + + def outer + pr = mp { return :good } + + foo(pr) + return :bad + end + end + + class DefineMethod + lamb = proc { return :good } + define_method :foo, lamb + + def outer + val = :bad + + # This is tricky, but works. If lamb properly returns, then the + # return value will go into val before we run the ensure. + # + # If lamb's return keeps unwinding incorrectly, val will still + # have it's old value. + # + # We can therefore use val to figure out what happened. + begin + val = foo() + ensure + if val != :good + return :bad + end + end + + return val + end + end + + class MethodWithBlock + def method1 + return [2, 3].inject 0 do |a, b| + a + b + end + nil + end + + def get_ary(count, &blk) + count.times.to_a do |i| + blk.call(i) if blk + end + end + + def method2 + return get_ary 3 do |i| + end + nil + end + end +end diff --git a/spec/ruby/language/fixtures/send.rb b/spec/ruby/language/fixtures/send.rb new file mode 100644 index 0000000000..c3013616b2 --- /dev/null +++ b/spec/ruby/language/fixtures/send.rb @@ -0,0 +1,140 @@ +module LangSendSpecs + module_function + + def fooM0; 100 end + def fooM1(a); [a]; end + def fooM2(a,b); [a,b]; end + def fooM3(a,b,c); [a,b,c]; end + def fooM4(a,b,c,d); [a,b,c,d]; end + def fooM5(a,b,c,d,e); [a,b,c,d,e]; end + def fooM0O1(a=1); [a]; end + def fooM1O1(a,b=1); [a,b]; end + def fooM2O1(a,b,c=1); [a,b,c]; end + def fooM3O1(a,b,c,d=1); [a,b,c,d]; end + def fooM4O1(a,b,c,d,e=1); [a,b,c,d,e]; end + def fooM0O2(a=1,b=2); [a,b]; end + def fooM0R(*r); r; end + def fooM1R(a, *r); [a, r]; end + def fooM0O1R(a=1, *r); [a, r]; end + def fooM1O1R(a, b=1, *r); [a, b, r]; end + + def one(a); a; end + def oneb(a,&b); [a,yield(b)]; end + def twob(a,b,&c); [a,b,yield(c)]; end + def makeproc(&b) b end + + def yield_now; yield; end + + def double(x); x * 2 end + def weird_parens + # means double((5).to_s) + # NOT (double(5)).to_s + double (5).to_s + end + + def rest_len(*a); a.size; end + + def self.twos(a,b,*c) + [c.size, c.last] + end + + class PrivateSetter + attr_reader :foo + attr_writer :foo + private :foo= + + def call_self_foo_equals(value) + self.foo = value + end + + def call_self_foo_equals_masgn(value) + a, self.foo = 1, value + end + end + + class PrivateGetter + attr_reader :foo + private :foo + + def call_self_foo + self.foo + end + + def call_self_foo_or_equals(value) + self.foo ||= 6 + end + end + + class AttrSet + attr_reader :result + def []=(a, b, c, d); @result = [a,b,c,d]; end + end + + class ToProc + def initialize(val) + @val = val + end + + def to_proc + Proc.new { @val } + end + end + + class ToAry + def initialize(obj) + @obj = obj + end + + def to_ary + @obj + end + end + + class MethodMissing + def initialize + @message = nil + @args = nil + end + + attr_reader :message, :args + + def method_missing(m, *a) + @message = m + @args = a + end + end + + class Attr19Set + attr_reader :result + def []=(*args); @result = args; end + end + + module_function + + def fooR(*r); r; end + def fooM0RQ1(*r, q); [r, q]; end + def fooM0RQ2(*r, s, q); [r, s, q]; end + def fooM1RQ1(a, *r, q); [a, r, q]; end + def fooM1O1RQ1(a, b=9, *r, q); [a, b, r, q]; end + def fooM1O1RQ2(a, b=9, *r, q, t); [a, b, r, q, t]; end + + def fooO1Q1(a=1, b); [a,b]; end + def fooM1O1Q1(a,b=2,c); [a,b,c]; end + def fooM2O1Q1(a,b,c=3,d); [a,b,c,d]; end + def fooM2O2Q1(a,b,c=3,d=4,e); [a,b,c,d,e]; end + def fooO4Q1(a=1,b=2,c=3,d=4,e); [a,b,c,d,e]; end + def fooO4Q2(a=1,b=2,c=3,d=4,e,f); [a,b,c,d,e,f]; end + + def destructure2((a,b)); a+b; end + def destructure2b((a,b)); [a,b]; end + def destructure4r((a,b,*c,d,e)); [a,b,c,d,e]; end + def destructure4o(a=1,(b,c),d,&e); [a,b,c,d]; end + def destructure5o(a=1, f=2, (b,c),d,&e); [a,f,b,c,d]; end + def destructure7o(a=1, f=2, (b,c),(d,e), &g); [a,f,b,c,d,e]; end + def destructure7b(a=1, f=2, (b,c),(d,e), &g); g.call([a,f,b,c,d,e]); end + def destructure4os(a=1,(b,*c)); [a,b,c]; end +end + +def lang_send_rest_len(*a) + a.size +end diff --git a/spec/ruby/language/fixtures/squiggly_heredoc.rb b/spec/ruby/language/fixtures/squiggly_heredoc.rb new file mode 100644 index 0000000000..afc87514c7 --- /dev/null +++ b/spec/ruby/language/fixtures/squiggly_heredoc.rb @@ -0,0 +1,39 @@ +module SquigglyHeredocSpecs + def self.message + <<~HEREDOC + character density, n.: + The number of very weird people in the office. + HEREDOC + end + + def self.blank + <<~HERE + HERE + end + + def self.unquoted + <<~HERE + unquoted #{"interpolated"} + HERE + end + + def self.doublequoted + <<~"HERE" + doublequoted #{"interpolated"} + HERE + end + + def self.singlequoted + <<~'HERE' + singlequoted #{"interpolated"} + HERE + end + + def self.least_indented_on_the_last_line + <<~HERE + a + b + c + HERE + end +end diff --git a/spec/ruby/language/fixtures/super.rb b/spec/ruby/language/fixtures/super.rb new file mode 100644 index 0000000000..4e89d59bed --- /dev/null +++ b/spec/ruby/language/fixtures/super.rb @@ -0,0 +1,569 @@ +module Super + module S1 + class A + def foo(a) + a << "A#foo" + bar(a) + end + def bar(a) + a << "A#bar" + end + end + class B < A + def foo(a) + a << "B#foo" + super(a) + end + def bar(a) + a << "B#bar" + super(a) + end + end + end + + module S2 + class A + def baz(a) + a << "A#baz" + end + end + class B < A + def foo(a) + a << "B#foo" + baz(a) + end + end + class C < B + def baz(a) + a << "C#baz" + super(a) + end + end + end + + module S3 + class A + def foo(a) + a << "A#foo" + end + def self.foo(a) + a << "A.foo" + end + def self.bar(a) + a << "A.bar" + foo(a) + end + end + class B < A + def self.foo(a) + a << "B.foo" + super(a) + end + def self.bar(a) + a << "B.bar" + super(a) + end + end + end + + module S4 + class A + def foo(a) + a << "A#foo" + end + end + class B < A + def foo(a, b) + a << "B#foo(a,#{b})" + super(a) + end + end + end + + class S5 + def here + :good + end + end + + class S6 < S5 + def under + yield + end + + def here + under { + super + } + end + end + + class S7 < S5 + define_method(:here) { super() } + end + + module MS1 + module ModA + def foo(a) + a << "ModA#foo" + bar(a) + end + def bar(a) + a << "ModA#bar" + end + end + class A + include ModA + end + module ModB + def bar(a) + a << "ModB#bar" + super(a) + end + end + class B < A + def foo(a) + a << "B#foo" + super(a) + end + include ModB + end + end + + module MS2 + class A + def baz(a) + a << "A#baz" + end + end + module ModB + def foo(a) + a << "ModB#foo" + baz(a) + end + end + class B < A + include ModB + end + class C < B + def baz(a) + a << "C#baz" + super(a) + end + end + end + + module MultiSuperTargets + module M + def foo + super + end + end + + class BaseA + def foo + :BaseA + end + end + + class BaseB + def foo + :BaseB + end + end + + class A < BaseA + include M + end + + class B < BaseB + include M + end + end + + module MS3 + module ModA + def foo(a) + a << "ModA#foo" + end + def bar(a) + a << "ModA#bar" + foo(a) + end + end + class A + def foo(a) + a << "A#foo" + end + class << self + include ModA + end + end + class B < A + def self.foo(a) + a << "B.foo" + super(a) + end + def self.bar(a) + a << "B.bar" + super(a) + end + end + end + + module MS4 + module Layer1 + def example + 5 + end + end + + module Layer2 + include Layer1 + def example + super + end + end + + class A + include Layer2 + public :example + end + end + + class MM_A + undef_method :is_a? + end + + class MM_B < MM_A + def is_a?(blah) + # should fire the method_missing below + super + end + + def method_missing(*) + false + end + end + + class Alias1 + def name + [:alias1] + end + end + + class Alias2 < Alias1 + def initialize + @times = 0 + end + + def name + if @times >= 10 + raise "runaway super" + end + + @times += 1 + + # Use this so that we can see collect all supers that we see. + # One bug that arises is that we call Alias2#name from Alias2#name + # as it's superclass. In that case, either we get a runaway recursion + # super OR we get the return value being [:alias2, :alias2, :alias1] + # rather than [:alias2, :alias1]. + # + # Which one depends on caches and how super is implemented. + [:alias2] + super + end + end + + class Alias3 < Alias2 + alias_method :name3, :name + # In the method table for Alias3 now should be a special alias entry + # that references Alias2 and Alias2#name (probably as an object). + # + # When name3 is called then, Alias2 (NOT Alias3) is presented as the + # current module to Alias2#name, so that when super is called, + # Alias2->superclass is next. + # + # Otherwise, Alias2 is next, which is where name was to begin with, + # causing the wrong #name method to be called. + end + + module AliasWithSuper + module AS1 + def foo + :a + end + end + + module BS1 + def foo + [:b, super] + end + end + + class Base + extend AS1 + extend BS1 + end + + class Trigger < Base + class << self + def foo_quux + foo_baz + end + + alias_method :foo_baz, :foo + alias_method :foo, :foo_quux + end + end + end + + module RestArgsWithSuper + class A + def a(*args) + args + end + end + + class B < A + def a(*args) + args << "foo" + + super + end + end + end + + class AnonymousModuleIncludedTwiceBase + def self.whatever + mod = Module.new do + def a(array) + array << "anon" + super + end + end + + include mod + end + + def a(array) + array << "non-anon" + end + end + + class AnonymousModuleIncludedTwice < AnonymousModuleIncludedTwiceBase + whatever + whatever + end + + module ZSuperWithBlock + class A + def a + yield + end + + def b(&block) + block.call + end + + def c + yield + end + end + + class B < A + def a + super { 14 } + end + + def b + block_ref = lambda { 15 } + [super { 14 }, super(&block_ref)] + end + + def c + block_ref = lambda { 16 } + super(&block_ref) + end + end + end + + module ZSuperWithOptional + class A + def m(x, y, z) + z + end + end + + class B < A + def m(x, y, z = 14) + super + end + end + + class C < A + def m(x, y, z = 14) + z = 100 + super + end + end + end + + module ZSuperWithRest + class A + def m(*args) + args + end + + def m_modified(*args) + args + end + end + + class B < A + def m(*args) + super + end + + def m_modified(*args) + args[1] = 14 + super + end + end + end + + module ZSuperWithRestAndOthers + class A + def m(a, b, *args) + args + end + + def m_modified(a, b, *args) + args + end + end + + class B < A + def m(a, b, *args) + super + end + + def m_modified(a, b, *args) + args[1] = 14 + super + end + end + end + + module ZSuperWithUnderscores + class A + def m(*args) + args + end + + def m_modified(*args) + args + end + end + + class B < A + def m(_, _) + super + end + + def m_modified(_, _) + _ = 14 + super + end + end + end + + module KeywordArguments + class A + def foo(**args) + args + end + end + + class B < A + def foo(**) + super + end + end + + class C < A + end + end + + module FromBasicObject + def __send__(name, *args, &block) + super + end + end + + module IntermediateBasic + include FromBasicObject + end + + class IncludesFromBasic + include FromBasicObject + + def foobar; 43; end + end + + class IncludesIntermediate + include IntermediateBasic + + def foobar; 42; end + end + + module SingletonCase + class Base + def foobar(array) + array << :base + end + end + + class Foo < Base + def foobar(array) + array << :foo + super + end + end + end + + module SingletonAliasCase + class Base + def foobar(array) + array << :base + end + + def alias_on_singleton + object = self + singleton = (class << object; self; end) + singleton.__send__(:alias_method, :new_foobar, :foobar) + end + end + + class Foo < Base + def foobar(array) + array << :foo + super + end + end + end + + module SplatAndKeyword + class A + def foo(*args, **options) + [args, options] + end + end + + class B < A + def foo(*args, **options) + super + end + end + end +end diff --git a/spec/ruby/language/fixtures/variables.rb b/spec/ruby/language/fixtures/variables.rb new file mode 100644 index 0000000000..07265dbb2b --- /dev/null +++ b/spec/ruby/language/fixtures/variables.rb @@ -0,0 +1,85 @@ +module VariablesSpecs + class ParAsgn + attr_accessor :x + + def initialize + @x = 0 + end + + def inc + @x += 1 + end + + def to_ary + [1,2,3,4] + end + end + + class OpAsgn + attr_accessor :a, :b, :side_effect + + def do_side_effect + self.side_effect = true + return @a + end + + def do_more_side_effects + @a += 5 + self + end + + def do_bool_side_effects + @b += 1 + self + end + end + + class Hashalike + def [](k) k end + def []=(k, v) [k, v] end + end + + def self.reverse_foo(a, b) + return b, a + end + + class ArrayLike + def initialize(array) + @array = array + end + + def to_a + @array + end + end + + class ArraySubclass < Array + end + + class PrivateMethods + private + + def to_ary + [1, 2] + end + + def to_a + [3, 4] + end + end + + class ToAryNil + def to_ary + end + end + + class Chain + def self.without_parenthesis a + a + end + end + + def self.false + false + end +end diff --git a/spec/ruby/language/fixtures/yield.rb b/spec/ruby/language/fixtures/yield.rb new file mode 100644 index 0000000000..a195616640 --- /dev/null +++ b/spec/ruby/language/fixtures/yield.rb @@ -0,0 +1,37 @@ +module YieldSpecs + class Yielder + def z + yield + end + + def ze(&block) + block = proc { block } + yield + end + + def s(a) + yield(a) + end + + def m(a, b, c) + yield(a, b, c) + end + + def r(a) + yield(*a) + end + + def rs(a, b, c) + yield(a, b, *c) + end + + def self.define_deep(&inned_block) + define_method 'deep' do |v| + # should yield to inner_block + yield v + end + end + + define_deep { |v| v * 2} + end +end |