File: catch_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 (159 lines) | stat: -rw-r--r-- 4,263 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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)

describe "Kernel.catch" do
  before :each do
    ScratchPad.clear
  end

  it "executes its block and catches a thrown value matching its argument" do
    catch :thrown_key do
      ScratchPad.record :catch_block
      throw :thrown_key
      ScratchPad.record :throw_failed
    end
    ScratchPad.recorded.should == :catch_block
  end

  it "returns the second value passed to throw" do
    catch(:thrown_key) { throw :thrown_key, :catch_value }.should == :catch_value
  end

  it "returns the last expression evaluated if throw was not called" do
    catch(:thrown_key) { 1; :catch_block }.should == :catch_block
  end

  it "passes the given symbol to its block" do
    catch :thrown_key do |tag|
      ScratchPad.record tag
    end
    ScratchPad.recorded.should == :thrown_key
  end

  ruby_version_is ""..."1.9" do
    it "matches strings as symbols" do
      catch "thrown_key" do
        ScratchPad.record :catch_block
        throw :thrown_key
      end
      ScratchPad.recorded.should == :catch_block
    end

    it "matches strings that are the same value" do
      catch "thrown_key" do
        ScratchPad.record :catch_block
        throw "thrown_key"
      end
      ScratchPad.recorded.should == :catch_block
    end

    it "raises a TypeError if the argument is an Object" do
      lambda { catch(Object.new) {} }.should raise_error(TypeError)
    end

    it "raises an ArgumentError if called without an argument" do
      lambda { catch {} }.should raise_error(ArgumentError)
    end

    it "passes a symbol converted from the given string to its block" do
      catch("thrown_key") { |tag| tag }.should == :thrown_key
    end
  end

  ruby_version_is "1.9" do
    it "raises an ArgumentError if a Symbol is thrown for a String catch value" do
      lambda { catch("exit") { throw :exit } }.should raise_error(ArgumentError)
    end

    it "raises an ArgumentError if a String with different identity is thrown" do
      lambda { catch("exit") { throw "exit" } }.should raise_error(ArgumentError)
    end

    it "catches a Symbol when thrown a matching Symbol" do
      catch :thrown_key do
        ScratchPad.record :catch_block
        throw :thrown_key
      end
      ScratchPad.recorded.should == :catch_block
    end

    it "catches a String when thrown a String with the same identity" do
      key = "thrown_key"
      catch key do
        ScratchPad.record :catch_block
        throw key
      end
      ScratchPad.recorded.should == :catch_block
    end

    it "accepts an object as an argument" do
      catch(Object.new) { :catch_block }.should == :catch_block
    end

    it "yields an object when called without arguments" do
      catch { |tag| tag }.should be_an_instance_of(Object)
    end
  end

  it "can be used even in a method different from where throw is called" do
    class CatchSpecs
      def self.throwing_method
        throw :blah, :thrown_value
      end
      def self.catching_method
        catch :blah do
          throwing_method
        end
      end
    end
    CatchSpecs.catching_method.should == :thrown_value
  end

  describe "when nested" do
    before :each do
      ScratchPad.record []
    end

    it "catches across invocation boundaries" do
      catch :one do
        ScratchPad << 1
        catch :two do
          ScratchPad << 2
          catch :three do
            ScratchPad << 3
            throw :one
            ScratchPad << 4
          end
          ScratchPad << 5
        end
        ScratchPad << 6
      end

      ScratchPad.recorded.should == [1, 2, 3]
    end

    it "catches in the nested invocation with the same key object" do
      catch :thrown_key do
        ScratchPad << 1
        catch :thrown_key do
          ScratchPad << 2
          throw :thrown_key
          ScratchPad << 3
        end
        ScratchPad << 4
      end

      ScratchPad.recorded.should == [1, 2, 4]
    end
  end

  it "raises LocalJumpError if no block is given" do
    lambda { catch :blah }.should raise_error(LocalJumpError)
  end
end

describe "Kernel#catch" do
  it "is a private method" do
    Kernel.should have_private_instance_method(:catch)
  end
end