summaryrefslogtreecommitdiff
path: root/spec/ruby/core/main
diff options
context:
space:
mode:
Diffstat (limited to 'spec/ruby/core/main')
-rw-r--r--spec/ruby/core/main/define_method_spec.rb28
-rw-r--r--spec/ruby/core/main/fixtures/classes.rb26
-rw-r--r--spec/ruby/core/main/fixtures/string_refinement.rb7
-rw-r--r--spec/ruby/core/main/fixtures/string_refinement_user.rb11
-rw-r--r--spec/ruby/core/main/fixtures/using.rb1
-rw-r--r--spec/ruby/core/main/fixtures/using_in_main.rb5
-rw-r--r--spec/ruby/core/main/fixtures/using_in_method.rb5
-rw-r--r--spec/ruby/core/main/fixtures/wrapped_include.rb1
-rw-r--r--spec/ruby/core/main/include_spec.rb16
-rw-r--r--spec/ruby/core/main/private_spec.rb42
-rw-r--r--spec/ruby/core/main/public_spec.rb43
-rw-r--r--spec/ruby/core/main/ruby2_keywords_spec.rb9
-rw-r--r--spec/ruby/core/main/to_s_spec.rb7
-rw-r--r--spec/ruby/core/main/using_spec.rb150
14 files changed, 351 insertions, 0 deletions
diff --git a/spec/ruby/core/main/define_method_spec.rb b/spec/ruby/core/main/define_method_spec.rb
new file mode 100644
index 0000000000..d85c5e8119
--- /dev/null
+++ b/spec/ruby/core/main/define_method_spec.rb
@@ -0,0 +1,28 @@
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+
+script_binding = binding
+
+describe "main#define_method" do
+ before :each do
+ @code = 'define_method(:boom) { :bam }'
+ end
+
+ after :each do
+ Object.send :remove_method, :boom
+ end
+
+ it 'creates a public method in TOPLEVEL_BINDING' do
+ eval @code, TOPLEVEL_BINDING
+ Object.should have_method :boom
+ end
+
+ it 'creates a public method in script binding' do
+ eval @code, script_binding
+ Object.should have_method :boom
+ end
+
+ it 'returns the method name as symbol' do
+ eval(@code, TOPLEVEL_BINDING).should equal :boom
+ end
+end
diff --git a/spec/ruby/core/main/fixtures/classes.rb b/spec/ruby/core/main/fixtures/classes.rb
new file mode 100644
index 0000000000..757cee4e4a
--- /dev/null
+++ b/spec/ruby/core/main/fixtures/classes.rb
@@ -0,0 +1,26 @@
+module MainSpecs
+ module Module
+ end
+
+ module WrapIncludeModule
+ end
+
+ DATA = {}
+end
+
+
+def main_public_method
+end
+public :main_public_method
+
+def main_public_method2
+end
+public :main_public_method2
+
+def main_private_method
+end
+private :main_private_method
+
+def main_private_method2
+end
+private :main_private_method2
diff --git a/spec/ruby/core/main/fixtures/string_refinement.rb b/spec/ruby/core/main/fixtures/string_refinement.rb
new file mode 100644
index 0000000000..2dc6de52ca
--- /dev/null
+++ b/spec/ruby/core/main/fixtures/string_refinement.rb
@@ -0,0 +1,7 @@
+module StringRefinement
+ refine(String) do
+ def foo
+ 'foo'
+ end
+ end
+end
diff --git a/spec/ruby/core/main/fixtures/string_refinement_user.rb b/spec/ruby/core/main/fixtures/string_refinement_user.rb
new file mode 100644
index 0000000000..48620c325f
--- /dev/null
+++ b/spec/ruby/core/main/fixtures/string_refinement_user.rb
@@ -0,0 +1,11 @@
+using StringRefinement
+
+module MainSpecs
+ DATA[:in_module] = 'hello'.foo
+
+ def self.call_foo(x)
+ x.foo
+ end
+end
+
+MainSpecs::DATA[:toplevel] = 'hello'.foo
diff --git a/spec/ruby/core/main/fixtures/using.rb b/spec/ruby/core/main/fixtures/using.rb
new file mode 100644
index 0000000000..30713ef309
--- /dev/null
+++ b/spec/ruby/core/main/fixtures/using.rb
@@ -0,0 +1 @@
+using Module.new
diff --git a/spec/ruby/core/main/fixtures/using_in_main.rb b/spec/ruby/core/main/fixtures/using_in_main.rb
new file mode 100644
index 0000000000..a4a71c89cc
--- /dev/null
+++ b/spec/ruby/core/main/fixtures/using_in_main.rb
@@ -0,0 +1,5 @@
+MAIN = self
+
+module X
+ MAIN.send(:using, Module.new)
+end
diff --git a/spec/ruby/core/main/fixtures/using_in_method.rb b/spec/ruby/core/main/fixtures/using_in_method.rb
new file mode 100644
index 0000000000..d9ea2e9ef0
--- /dev/null
+++ b/spec/ruby/core/main/fixtures/using_in_method.rb
@@ -0,0 +1,5 @@
+def foo
+ using Module.new
+end
+
+foo
diff --git a/spec/ruby/core/main/fixtures/wrapped_include.rb b/spec/ruby/core/main/fixtures/wrapped_include.rb
new file mode 100644
index 0000000000..307c98b419
--- /dev/null
+++ b/spec/ruby/core/main/fixtures/wrapped_include.rb
@@ -0,0 +1 @@
+include MainSpecs::WrapIncludeModule
diff --git a/spec/ruby/core/main/include_spec.rb b/spec/ruby/core/main/include_spec.rb
new file mode 100644
index 0000000000..9f5a5f54ea
--- /dev/null
+++ b/spec/ruby/core/main/include_spec.rb
@@ -0,0 +1,16 @@
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+
+describe "main#include" do
+ it "includes the given Module in Object" do
+ eval "include MainSpecs::Module", TOPLEVEL_BINDING
+ Object.ancestors.should include(MainSpecs::Module)
+ end
+
+ context "in a file loaded with wrapping" do
+ it "includes the given Module in the load wrapper" do
+ load(File.expand_path("../fixtures/wrapped_include.rb", __FILE__), true)
+ Object.ancestors.should_not include(MainSpecs::WrapIncludeModule)
+ end
+ end
+end
diff --git a/spec/ruby/core/main/private_spec.rb b/spec/ruby/core/main/private_spec.rb
new file mode 100644
index 0000000000..76895fd649
--- /dev/null
+++ b/spec/ruby/core/main/private_spec.rb
@@ -0,0 +1,42 @@
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+
+describe "main#private" do
+ after :each do
+ Object.send(:public, :main_public_method)
+ Object.send(:public, :main_public_method2)
+ end
+
+ context "when single argument is passed and it is not an array" do
+ it "sets the visibility of the given methods to private" do
+ eval "private :main_public_method", TOPLEVEL_BINDING
+ Object.should have_private_method(:main_public_method)
+ end
+ end
+
+ context "when multiple arguments are passed" do
+ it "sets the visibility of the given methods to private" do
+ eval "private :main_public_method, :main_public_method2", TOPLEVEL_BINDING
+ Object.should have_private_method(:main_public_method)
+ Object.should have_private_method(:main_public_method2)
+ end
+ end
+
+ context "when single argument is passed and is an array" do
+ it "sets the visibility of the given methods to private" do
+ eval "private [:main_public_method, :main_public_method2]", TOPLEVEL_BINDING
+ Object.should have_private_method(:main_public_method)
+ Object.should have_private_method(:main_public_method2)
+ end
+ end
+
+ it "returns argument" do
+ eval("private :main_public_method", TOPLEVEL_BINDING).should equal(:main_public_method)
+ end
+
+ it "raises a NameError when at least one of given method names is undefined" do
+ -> do
+ eval "private :main_public_method, :main_undefined_method", TOPLEVEL_BINDING
+ end.should raise_error(NameError)
+ end
+end
diff --git a/spec/ruby/core/main/public_spec.rb b/spec/ruby/core/main/public_spec.rb
new file mode 100644
index 0000000000..3c77798fbc
--- /dev/null
+++ b/spec/ruby/core/main/public_spec.rb
@@ -0,0 +1,43 @@
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+
+describe "main#public" do
+ after :each do
+ Object.send(:private, :main_private_method)
+ Object.send(:private, :main_private_method2)
+ end
+
+ context "when single argument is passed and it is not an array" do
+ it "sets the visibility of the given methods to public" do
+ eval "public :main_private_method", TOPLEVEL_BINDING
+ Object.should_not have_private_method(:main_private_method)
+ end
+ end
+
+ context "when multiple arguments are passed" do
+ it "sets the visibility of the given methods to public" do
+ eval "public :main_private_method, :main_private_method2", TOPLEVEL_BINDING
+ Object.should_not have_private_method(:main_private_method)
+ Object.should_not have_private_method(:main_private_method2)
+ end
+ end
+
+ context "when single argument is passed and is an array" do
+ it "sets the visibility of the given methods to public" do
+ eval "public [:main_private_method, :main_private_method2]", TOPLEVEL_BINDING
+ Object.should_not have_private_method(:main_private_method)
+ Object.should_not have_private_method(:main_private_method2)
+ end
+ end
+
+ it "returns argument" do
+ eval("public :main_private_method", TOPLEVEL_BINDING).should equal(:main_private_method)
+ end
+
+
+ it "raises a NameError when given an undefined name" do
+ -> do
+ eval "public :main_undefined_method", TOPLEVEL_BINDING
+ end.should raise_error(NameError)
+ end
+end
diff --git a/spec/ruby/core/main/ruby2_keywords_spec.rb b/spec/ruby/core/main/ruby2_keywords_spec.rb
new file mode 100644
index 0000000000..27ceae3253
--- /dev/null
+++ b/spec/ruby/core/main/ruby2_keywords_spec.rb
@@ -0,0 +1,9 @@
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+
+describe "main.ruby2_keywords" do
+ it "is the same as Object.ruby2_keywords" do
+ main = TOPLEVEL_BINDING.receiver
+ main.should have_private_method(:ruby2_keywords)
+ end
+end
diff --git a/spec/ruby/core/main/to_s_spec.rb b/spec/ruby/core/main/to_s_spec.rb
new file mode 100644
index 0000000000..642cfa4433
--- /dev/null
+++ b/spec/ruby/core/main/to_s_spec.rb
@@ -0,0 +1,7 @@
+require_relative '../../spec_helper'
+
+describe "main#to_s" do
+ it "returns 'main'" do
+ eval('to_s', TOPLEVEL_BINDING).should == "main"
+ end
+end
diff --git a/spec/ruby/core/main/using_spec.rb b/spec/ruby/core/main/using_spec.rb
new file mode 100644
index 0000000000..5b9a751595
--- /dev/null
+++ b/spec/ruby/core/main/using_spec.rb
@@ -0,0 +1,150 @@
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+
+describe "main.using" do
+ it "requires one Module argument" do
+ -> do
+ eval('using', TOPLEVEL_BINDING)
+ end.should raise_error(ArgumentError)
+
+ -> do
+ eval('using "foo"', TOPLEVEL_BINDING)
+ end.should raise_error(TypeError)
+ end
+
+ it "uses refinements from the given module only in the target file" do
+ require_relative 'fixtures/string_refinement'
+ load File.expand_path('../fixtures/string_refinement_user.rb', __FILE__)
+ MainSpecs::DATA[:in_module].should == 'foo'
+ MainSpecs::DATA[:toplevel].should == 'foo'
+ -> do
+ 'hello'.foo
+ end.should raise_error(NoMethodError)
+ end
+
+ it "uses refinements from the given module for method calls in the target file" do
+ require_relative 'fixtures/string_refinement'
+ load File.expand_path('../fixtures/string_refinement_user.rb', __FILE__)
+ -> do
+ 'hello'.foo
+ end.should raise_error(NoMethodError)
+ MainSpecs.call_foo('hello').should == 'foo'
+ end
+
+ it "uses refinements from the given module in the eval string" do
+ cls = MainSpecs::DATA[:cls] = Class.new {def foo; 'foo'; end}
+ MainSpecs::DATA[:mod] = Module.new do
+ refine(cls) do
+ def foo; 'bar'; end
+ end
+ end
+ eval(<<-EOS, TOPLEVEL_BINDING).should == 'bar'
+ using MainSpecs::DATA[:mod]
+ MainSpecs::DATA[:cls].new.foo
+ EOS
+ end
+
+ it "does not affect methods defined before it is called" do
+ cls = Class.new {def foo; 'foo'; end}
+ MainSpecs::DATA[:mod] = Module.new do
+ refine(cls) do
+ def foo; 'bar'; end
+ end
+ end
+ x = MainSpecs::DATA[:x] = Object.new
+ eval <<-EOS, TOPLEVEL_BINDING
+ x = MainSpecs::DATA[:x]
+ def x.before_using(obj)
+ obj.foo
+ end
+ using MainSpecs::DATA[:mod]
+ def x.after_using(obj)
+ obj.foo
+ end
+ EOS
+
+ obj = cls.new
+ x.before_using(obj).should == 'foo'
+ x.after_using(obj).should == 'bar'
+ end
+
+ it "propagates refinements added to existing modules after it is called" do
+ cls = Class.new {def foo; 'foo'; end}
+ mod = MainSpecs::DATA[:mod] = Module.new do
+ refine(cls) do
+ def foo; 'quux'; end
+ end
+ end
+ x = MainSpecs::DATA[:x] = Object.new
+ eval <<-EOS, TOPLEVEL_BINDING
+ using MainSpecs::DATA[:mod]
+ x = MainSpecs::DATA[:x]
+ def x.call_foo(obj)
+ obj.foo
+ end
+ def x.call_bar(obj)
+ obj.bar
+ end
+ EOS
+
+ obj = cls.new
+ x.call_foo(obj).should == 'quux'
+
+ mod.module_eval do
+ refine(cls) do
+ def bar; 'quux'; end
+ end
+ end
+
+ x.call_bar(obj).should == 'quux'
+ end
+
+ it "does not propagate refinements of new modules added after it is called" do
+ cls = Class.new {def foo; 'foo'; end}
+ cls2 = Class.new {def bar; 'bar'; end}
+ mod = MainSpecs::DATA[:mod] = Module.new do
+ refine(cls) do
+ def foo; 'quux'; end
+ end
+ end
+ x = MainSpecs::DATA[:x] = Object.new
+ eval <<-EOS, TOPLEVEL_BINDING
+ using MainSpecs::DATA[:mod]
+ x = MainSpecs::DATA[:x]
+ def x.call_foo(obj)
+ obj.foo
+ end
+ def x.call_bar(obj)
+ obj.bar
+ end
+ EOS
+
+ x.call_foo(cls.new).should == 'quux'
+
+ mod.module_eval do
+ refine(cls2) do
+ def bar; 'quux'; end
+ end
+ end
+
+ x.call_bar(cls2.new).should == 'bar'
+ end
+
+ it "raises error when called from method in wrapped script" do
+ -> do
+ load File.expand_path('../fixtures/using_in_method.rb', __FILE__), true
+ end.should raise_error(RuntimeError)
+ end
+
+ it "raises error when called on toplevel from module" do
+ -> do
+ load File.expand_path('../fixtures/using_in_main.rb', __FILE__), true
+ end.should raise_error(RuntimeError)
+ end
+
+ it "does not raise error when wrapped with module" do
+ -> do
+ load File.expand_path('../fixtures/using.rb', __FILE__), true
+ end.should_not raise_error
+ end
+end