File: instance_exec_spec.rb

package info (click to toggle)
jruby 1.7.26-1%2Bdeb9u1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 84,572 kB
  • sloc: ruby: 669,910; java: 253,056; xml: 35,152; ansic: 9,187; yacc: 7,267; cpp: 5,244; sh: 1,036; makefile: 345; jsp: 48; tcl: 40
file content (110 lines) | stat: -rw-r--r-- 3,577 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
require File.expand_path('../../../spec_helper', __FILE__)

ruby_version_is "1.8.7" do

  require File.expand_path('../fixtures/classes', __FILE__)

  describe "Object#instance_exec" do
    it "raises a LocalJumpError unless given a block" do
      lambda { "hola".instance_exec }.should raise_error(LocalJumpError)
    end

    it "has an arity of -1" do
      Object.new.method(:instance_exec).arity.should == -1
    end

    it "accepts arguments with a block" do
      lambda { "hola".instance_exec(4, 5) { |a,b| a + b } }.should_not raise_error
    end

    it "doesn't pass self to the block as an argument" do
      "hola".instance_exec { |o| o }.should be_nil
    end

    it "passes any arguments to the block" do
      Object.new.instance_exec(1,2) {|one, two| one + two}.should == 3
    end

    it "only binds the exec to the receiver" do
      f = Object.new
      f.instance_exec do
        def foo
          1
        end
      end
      f.foo.should == 1
      lambda { Object.new.foo }.should raise_error(NoMethodError)
    end

    # TODO: This should probably be replaced with a "should behave like" that uses
    # the many scoping/binding specs from kernel/eval_spec, since most of those
    # behaviors are the same for instance_exec. See also module_eval/class_eval.

    it "binds self to the receiver" do
      s = "hola"
      (s == s.instance_exec { self }).should == true
    end
    
    it "binds the block's binding self to the receiver" do
      s = "hola"
      (s == s.instance_exec { eval "self", binding }).should == true
    end

    it "executes in the context of the receiver" do
      "Ruby-fu".instance_exec { size }.should == 7
      Object.class_eval { "Ruby-fu".instance_exec{ to_s } }.should == "Ruby-fu"
    end

    it "has access to receiver's instance variables" do
      ObjectSpecs::IVars.new.instance_exec { @secret }.should == 99
    end

    it "invokes Method objects without rebinding self" do
      3.instance_exec(4, &5.method(:+)).should == 9
    end

    ruby_version_is ""..."1.9" do
      it "sets class variables in the receiver" do
        ObjectSpecs::InstExec.class_variables.should include("@@count")
        ObjectSpecs::InstExec.send(:class_variable_get, :@@count).should == 2
      end
    end

    ruby_version_is "1.9" do
       it "sets class variables in the receiver" do
        ObjectSpecs::InstExec.class_variables.should include(:@@count)
        ObjectSpecs::InstExec.send(:class_variable_get, :@@count).should == 2
      end
    end

    it "raises a TypeError when defining methods on an immediate" do
      lambda do
        1.instance_exec { def foo; end }
      end.should raise_error(TypeError)
      lambda do
        :foo.instance_exec { def foo; end }
      end.should raise_error(TypeError)
    end

  quarantine! do # Not clean, leaves cvars lying around to break other specs
    it "scopes class var accesses in the caller when called on a Fixnum" do
      # Fixnum can take instance vars
      Fixnum.class_eval "@@__tmp_instance_exec_spec = 1"
      (defined? @@__tmp_instance_exec_spec).should == nil

      @@__tmp_instance_exec_spec = 2
      1.instance_exec { @@__tmp_instance_exec_spec }.should == 2
      Fixnum.__send__(:remove_class_variable, :@@__tmp_instance_exec_spec)
    end
  end

    it "raises a TypeError when defining methods on numerics" do
      lambda do
        (1.0).instance_exec { def foo; end }
      end.should raise_error(TypeError)
      lambda do
        (1 << 64).instance_exec { def foo; end }
      end.should raise_error(TypeError)
    end
  end
end