Class: Riot::Assertion

Inherits:
RunnableBlock show all
Defined in:
lib/riot/assertion.rb

Overview

An Assertion is the engine behind evaluating a single test that can be reported on. When asserts or denies is used, the description and assertion block are used to generate a single Assertion instance. When running an Assertion, a [Riot::Situation] instance is required for data scoping. The result of calling run will be a status tuple that can be used for reporting.

In general, you won’t be spending much time in here.

Direct Known Subclasses

RR::Assertion

Instance Attribute Summary

Attributes inherited from RunnableBlock

#definition

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from RunnableBlock

#to_s

Constructor Details

#initialize(description, negative = false, &definition) ⇒ Assertion

Setups a new Assertion. By default, the assertion will be a “positive” one, which means evaluate will be call on the associated assertion macro. If negative is true, devaluate will be called instead. Not providing a definition block is just kind of silly since it’s used to generate the actual value for evaluation by a macro.

Parameters:

  • definition (String)

    A small description of what this assertion is testing

  • negative (Boolean) (defaults to: false)

    Determines whether this is a positive or negative assertion

  • definition (lambda)

    The block that will return the actual value when eval’ed



34
35
36
37
38
39
# File 'lib/riot/assertion.rb', line 34

def initialize(description, negative=false, &definition)
  super(description, &definition)
  @negative = negative
  @expectings, @expectation_block = [], nil
  @macro = AssertionMacro.default
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missingObject (private)

Raises:

  • (NoMethodError)


64
65
66
67
68
69
70
# File 'lib/riot/assertion.rb', line 64

def enhance_with_macro(name, *expectings, &expectation_block)
  @expectings, @expectation_block = expectings, expectation_block
  @macro = self.class.macros[name.to_s].new
  raise(NoMethodError, name) unless @macro
  @macro.file, @macro.line = caller.first.match(/(.*):(\d+)/)[1..2]
  self
end

Class Method Details

.macrosHash<Riot::AssertionMacro>

Returns the list of assertion macros that have been successfully registered

Returns:



13
# File 'lib/riot/assertion.rb', line 13

def macros; @@macros ||= {}; end

.register_macro(name, assertion_macro) ⇒ Object

Registers a [Riot::AssertionMacro] class to a given name. Name is distinct, which means any future registrations for the same name will replace previous ones. name will always be converted to a string first.

Parameters:

  • name (String, Symbol)

    The handle the macro will be associated with

  • assertion_macro (Class)

    A [Riot::AssertionMacro] class



21
22
23
# File 'lib/riot/assertion.rb', line 21

def register_macro(name, assertion_macro)
  macros[name.to_s] = assertion_macro
end

Instance Method Details

#run(situation) ⇒ Array<Symbol, String>

Given a Situation, execute the assertion definition provided to this Assertion, hand off to an assertion macro for evaluation, and then return a status tuple. If the macro to be used expects any exception, catch the exception and send to the macro; else just return it back.

Currently supporting 3 evaluation states: :pass, :fail, and :error

Parameters:

Returns:

  • (Array<Symbol, String>)

    array containing evaluation state and a descriptive explanation



49
50
51
52
53
54
55
# File 'lib/riot/assertion.rb', line 49

def run(situation)
  @expectings << situation.evaluate(&@expectation_block) if @expectation_block
  actual = situation.evaluate(&definition)
  assert((@macro.expects_exception? ? nil : actual), *@expectings)
rescue Exception => e
  @macro.expects_exception? ? assert(e, *@expectings) : @macro.error(e)
end