Module: Ayudante::AssertChanges

Included in:
Test::Unit::TestCase
Defined in:
lib/ayudante/assert_changes.rb

Instance Method Summary collapse

Instance Method Details

#assert_changes(transitions, &block) ⇒ Object

Assertion that a specific state changes during invocation of the passed in block.

i = 'simple'
assert_changes 'i' => 'whacky' do
   i = 'whacky'
end

This can be read “assert i changes to wacky”. Function will verify both the precondition (i is NOT wacky), and the post-condition.

This means i becomes nil during the block (and therefore non-nil

beforehand):
 assert_changes 'i' => nil do ...

If you want to specify a specific transition, you can do so by providing an array:

assert_changes 'i' => ['simple','whacky'] do

To specify that there should be no changes, use the symbol :no_change.

assert_changes 'i' => :no_change do

Finally, multiple assertions can be passed for larger sets of state changes:

i, j = 1,2
assert_changes 'i' => [1, 2], 'j' => [2, 1] do
   Mixer.mix(i,j)
end


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
# File 'lib/ayudante/assert_changes.rb', line 37

def assert_changes(transitions, &block)
  transitions = [transitions] if transitions.class==String
  if transitions.class == Array
    h = Hash.new
    transitions.each {|i| h[i] = :any_change}
    transitions = h
  end
  transitions.each  do |expression, value|
    result = eval(expression, block.__send__(:binding))
    if value == :no_change
      transitions[expression] = [result, result]
    elsif value == :any_change
      transitions[expression] = [result, :any_change]
    elsif value.nil?
      assert_not_nil(result, "Precondition not met")
    else
      pre_value = (value.class == Array) ? value[0] : !value
      assert_equal pre_value, result, "Precondition not met: " + expression
    end
  end
  yield
  transitions.each  do |expression, value|
    final_value = (value.class == Array) ? value[1] : value
    new_value = eval(expression, block.__send__(:binding))
    if final_value == :any_change
      assert value[0] != new_value, "Any change failed for " + expression
    else
      assert_equal final_value, new_value, "Change failed for " + expression
    end
  end
end

#assert_no_changes(transitions, &block) ⇒ Object



70
71
72
73
74
75
76
77
78
79
80
# File 'lib/ayudante/assert_changes.rb', line 70

def assert_no_changes(transitions, &block)
  if String === transitions
    assert_changes(transitions=>:no_change, &block)
  elsif Array === transitions
    assert_changes(transitions.inject({}) { |map, exp| map.merge(exp => :no_change) }, &block)
  else  # map
    map = {}
    transitions.each {|k, v| map[k]=[v, v]}
    assert_changes(map, &block)
  end
end