Module: Woulda::ShouldRaise::Macros

Defined in:
lib/woulda/should_raise/macros.rb

Instance Method Summary collapse

Instance Method Details

#should_raise(*args, &block) ⇒ Object

Make sure a block raises an exception. Call with optional arguments :instance_of/:kind_of and :message If :instance_of or :kind_of is specified, assert on the given type.

Otherwise only assert that an exception is raised.
Note: The shorthand should_raise(LoadError) is equivalent to should_raise(:instance_of => LoadError)

If :message is specified, will assert that exception.message =~ :message.

Examples:

should_raise {a block}
should_raise(LoadError) {a block}
should_raise(:instance_of => LoadError) {a block}
should_raise(:kind_of => LoadError) {a block}
should_raise(:message => "no such file to load") {a block}
should_raise(:message => /load/) {a block}
should_raise(LoadError, :message => /load/) {a block}
should_raise(:kind_of => LoadError, :message => /load/) {a block}
should_raise(:instance_of => LoadError, :message => /load/) {a block}

Raises:

  • (ArgumentError)


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
# File 'lib/woulda/should_raise/macros.rb', line 46

def should_raise(*args, &block)
  opts = args.last.is_a?(Hash) ? args.pop : {}

  if args.first.is_a?(Class)
    type  = args.first
    exact = true
  else
    type  = opts[:instance_of] || opts[:kind_of]
    exact = !!opts[:instance_of]
  end
  message = opts[:message]

  # Make sure we don't have a false sense of security and bork if incorrect options are supplied.
  [:message, :instance_of, :kind_of].each { |acceptable_arg| opts.delete(acceptable_arg) }
  raise ArgumentError, "Unknown parameter(s): #{opts.keys.inspect}. Only :message, :instance_of and :kind_of are supported." if opts.size > 0

  context "block #{block.inspect}" do # To avoid dupe test names. Any other ideas?
    should_string  = "raise an exception"
    should_string += " %s type #{type.inspect}" % (exact ? 'of' : 'descending from') if type
    
    should should_string do
      begin
        instance_eval &block
      rescue Exception => ex
        @raised_exception = ex
      end
      if @raised_exception && type
        if exact
          assert_instance_of type, @raised_exception
        else
          assert_kind_of type, @raised_exception
        end
      else
        assert @raised_exception, "The block was expected to raise an exception, but didn't"
      end
    end
  end

  if message
    context "raising an exception" do
      setup do
        begin
          instance_eval &block
        rescue Exception => ex
          @raised_exception = ex
        end
      end

      should "contain a message that matches #{message.inspect}" do
        assert_match message, @raised_exception.message
      end
    end
  end
end