mocha-macruby 0.9.8.20100129120100

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (172) hide show
  1. data/COPYING +3 -0
  2. data/MIT-LICENSE +7 -0
  3. data/README +39 -0
  4. data/RELEASE +294 -0
  5. data/Rakefile +214 -0
  6. data/examples/misc.rb +43 -0
  7. data/examples/mocha.rb +25 -0
  8. data/examples/stubba.rb +64 -0
  9. data/lib/mocha.rb +3 -0
  10. data/lib/mocha/any_instance_method.rb +59 -0
  11. data/lib/mocha/api.rb +173 -0
  12. data/lib/mocha/argument_iterator.rb +21 -0
  13. data/lib/mocha/backtrace_filter.rb +17 -0
  14. data/lib/mocha/cardinality.rb +95 -0
  15. data/lib/mocha/central.rb +27 -0
  16. data/lib/mocha/change_state_side_effect.rb +19 -0
  17. data/lib/mocha/class_method.rb +117 -0
  18. data/lib/mocha/configuration.rb +79 -0
  19. data/lib/mocha/deprecation.rb +22 -0
  20. data/lib/mocha/exception_raiser.rb +17 -0
  21. data/lib/mocha/expectation.rb +476 -0
  22. data/lib/mocha/expectation_error.rb +15 -0
  23. data/lib/mocha/expectation_list.rb +50 -0
  24. data/lib/mocha/in_state_ordering_constraint.rb +19 -0
  25. data/lib/mocha/inspect.rb +67 -0
  26. data/lib/mocha/instance_method.rb +16 -0
  27. data/lib/mocha/integration.rb +38 -0
  28. data/lib/mocha/integration/mini_test.rb +21 -0
  29. data/lib/mocha/integration/mini_test/assertion_counter.rb +23 -0
  30. data/lib/mocha/integration/mini_test/version_131_and_above.rb +50 -0
  31. data/lib/mocha/integration/test_unit.rb +40 -0
  32. data/lib/mocha/integration/test_unit/assertion_counter.rb +23 -0
  33. data/lib/mocha/integration/test_unit/gem_version_200.rb +49 -0
  34. data/lib/mocha/integration/test_unit/gem_version_201_and_above.rb +49 -0
  35. data/lib/mocha/integration/test_unit/ruby_version_185_and_below.rb +48 -0
  36. data/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb +50 -0
  37. data/lib/mocha/is_a.rb +9 -0
  38. data/lib/mocha/logger.rb +15 -0
  39. data/lib/mocha/metaclass.rb +13 -0
  40. data/lib/mocha/method_matcher.rb +21 -0
  41. data/lib/mocha/mock.rb +200 -0
  42. data/lib/mocha/mockery.rb +181 -0
  43. data/lib/mocha/module_method.rb +16 -0
  44. data/lib/mocha/multiple_yields.rb +20 -0
  45. data/lib/mocha/names.rb +53 -0
  46. data/lib/mocha/no_yields.rb +11 -0
  47. data/lib/mocha/object.rb +187 -0
  48. data/lib/mocha/parameter_matchers.rb +27 -0
  49. data/lib/mocha/parameter_matchers/all_of.rb +42 -0
  50. data/lib/mocha/parameter_matchers/any_of.rb +47 -0
  51. data/lib/mocha/parameter_matchers/any_parameters.rb +40 -0
  52. data/lib/mocha/parameter_matchers/anything.rb +33 -0
  53. data/lib/mocha/parameter_matchers/base.rb +15 -0
  54. data/lib/mocha/parameter_matchers/equals.rb +42 -0
  55. data/lib/mocha/parameter_matchers/has_entries.rb +45 -0
  56. data/lib/mocha/parameter_matchers/has_entry.rb +57 -0
  57. data/lib/mocha/parameter_matchers/has_key.rb +43 -0
  58. data/lib/mocha/parameter_matchers/has_value.rb +43 -0
  59. data/lib/mocha/parameter_matchers/includes.rb +41 -0
  60. data/lib/mocha/parameter_matchers/instance_of.rb +42 -0
  61. data/lib/mocha/parameter_matchers/is_a.rb +42 -0
  62. data/lib/mocha/parameter_matchers/kind_of.rb +42 -0
  63. data/lib/mocha/parameter_matchers/not.rb +42 -0
  64. data/lib/mocha/parameter_matchers/object.rb +15 -0
  65. data/lib/mocha/parameter_matchers/optionally.rb +55 -0
  66. data/lib/mocha/parameter_matchers/regexp_matches.rb +44 -0
  67. data/lib/mocha/parameter_matchers/responds_with.rb +43 -0
  68. data/lib/mocha/parameter_matchers/yaml_equivalent.rb +43 -0
  69. data/lib/mocha/parameters_matcher.rb +37 -0
  70. data/lib/mocha/pretty_parameters.rb +28 -0
  71. data/lib/mocha/return_values.rb +31 -0
  72. data/lib/mocha/sequence.rb +42 -0
  73. data/lib/mocha/single_return_value.rb +17 -0
  74. data/lib/mocha/single_yield.rb +18 -0
  75. data/lib/mocha/standalone.rb +1 -0
  76. data/lib/mocha/state_machine.rb +91 -0
  77. data/lib/mocha/stubbing_error.rb +16 -0
  78. data/lib/mocha/unexpected_invocation.rb +18 -0
  79. data/lib/mocha/yield_parameters.rb +31 -0
  80. data/lib/mocha_standalone.rb +2 -0
  81. data/lib/stubba.rb +4 -0
  82. data/test/acceptance/acceptance_test_helper.rb +38 -0
  83. data/test/acceptance/api_test.rb +139 -0
  84. data/test/acceptance/bug_18914_test.rb +43 -0
  85. data/test/acceptance/bug_21465_test.rb +34 -0
  86. data/test/acceptance/bug_21563_test.rb +25 -0
  87. data/test/acceptance/expected_invocation_count_test.rb +196 -0
  88. data/test/acceptance/failure_messages_test.rb +64 -0
  89. data/test/acceptance/minitest_test.rb +153 -0
  90. data/test/acceptance/mocha_example_test.rb +98 -0
  91. data/test/acceptance/mocha_test_result_test.rb +84 -0
  92. data/test/acceptance/mock_test.rb +100 -0
  93. data/test/acceptance/mock_with_initializer_block_test.rb +51 -0
  94. data/test/acceptance/mocked_methods_dispatch_test.rb +78 -0
  95. data/test/acceptance/optional_parameters_test.rb +70 -0
  96. data/test/acceptance/parameter_matcher_test.rb +209 -0
  97. data/test/acceptance/partial_mocks_test.rb +47 -0
  98. data/test/acceptance/return_value_test.rb +52 -0
  99. data/test/acceptance/sequence_test.rb +186 -0
  100. data/test/acceptance/states_test.rb +70 -0
  101. data/test/acceptance/stub_any_instance_method_test.rb +195 -0
  102. data/test/acceptance/stub_class_method_test.rb +203 -0
  103. data/test/acceptance/stub_everything_test.rb +56 -0
  104. data/test/acceptance/stub_instance_method_test.rb +203 -0
  105. data/test/acceptance/stub_module_method_test.rb +163 -0
  106. data/test/acceptance/stub_test.rb +52 -0
  107. data/test/acceptance/stubba_example_test.rb +102 -0
  108. data/test/acceptance/stubba_test.rb +15 -0
  109. data/test/acceptance/stubba_test_result_test.rb +66 -0
  110. data/test/acceptance/stubbing_error_backtrace_test.rb +64 -0
  111. data/test/acceptance/stubbing_method_unnecessarily_test.rb +65 -0
  112. data/test/acceptance/stubbing_non_existent_any_instance_method_test.rb +130 -0
  113. data/test/acceptance/stubbing_non_existent_class_method_test.rb +157 -0
  114. data/test/acceptance/stubbing_non_existent_instance_method_test.rb +147 -0
  115. data/test/acceptance/stubbing_non_public_any_instance_method_test.rb +130 -0
  116. data/test/acceptance/stubbing_non_public_class_method_test.rb +163 -0
  117. data/test/acceptance/stubbing_non_public_instance_method_test.rb +143 -0
  118. data/test/acceptance/stubbing_on_non_mock_object_test.rb +64 -0
  119. data/test/deprecation_disabler.rb +15 -0
  120. data/test/execution_point.rb +36 -0
  121. data/test/method_definer.rb +24 -0
  122. data/test/simple_counter.rb +13 -0
  123. data/test/test_helper.rb +25 -0
  124. data/test/test_runner.rb +33 -0
  125. data/test/unit/any_instance_method_test.rb +126 -0
  126. data/test/unit/array_inspect_test.rb +16 -0
  127. data/test/unit/backtrace_filter_test.rb +19 -0
  128. data/test/unit/cardinality_test.rb +56 -0
  129. data/test/unit/central_test.rb +65 -0
  130. data/test/unit/change_state_side_effect_test.rb +41 -0
  131. data/test/unit/class_method_test.rb +295 -0
  132. data/test/unit/configuration_test.rb +38 -0
  133. data/test/unit/date_time_inspect_test.rb +21 -0
  134. data/test/unit/exception_raiser_test.rb +42 -0
  135. data/test/unit/expectation_list_test.rb +57 -0
  136. data/test/unit/expectation_test.rb +480 -0
  137. data/test/unit/hash_inspect_test.rb +16 -0
  138. data/test/unit/in_state_ordering_constraint_test.rb +43 -0
  139. data/test/unit/metaclass_test.rb +22 -0
  140. data/test/unit/method_matcher_test.rb +23 -0
  141. data/test/unit/mock_test.rb +302 -0
  142. data/test/unit/mockery_test.rb +149 -0
  143. data/test/unit/multiple_yields_test.rb +18 -0
  144. data/test/unit/no_yields_test.rb +18 -0
  145. data/test/unit/object_inspect_test.rb +37 -0
  146. data/test/unit/object_test.rb +82 -0
  147. data/test/unit/parameter_matchers/all_of_test.rb +26 -0
  148. data/test/unit/parameter_matchers/any_of_test.rb +26 -0
  149. data/test/unit/parameter_matchers/anything_test.rb +21 -0
  150. data/test/unit/parameter_matchers/equals_test.rb +25 -0
  151. data/test/unit/parameter_matchers/has_entries_test.rb +51 -0
  152. data/test/unit/parameter_matchers/has_entry_test.rb +82 -0
  153. data/test/unit/parameter_matchers/has_key_test.rb +55 -0
  154. data/test/unit/parameter_matchers/has_value_test.rb +57 -0
  155. data/test/unit/parameter_matchers/includes_test.rb +44 -0
  156. data/test/unit/parameter_matchers/instance_of_test.rb +25 -0
  157. data/test/unit/parameter_matchers/is_a_test.rb +25 -0
  158. data/test/unit/parameter_matchers/kind_of_test.rb +25 -0
  159. data/test/unit/parameter_matchers/not_test.rb +26 -0
  160. data/test/unit/parameter_matchers/regexp_matches_test.rb +46 -0
  161. data/test/unit/parameter_matchers/responds_with_test.rb +25 -0
  162. data/test/unit/parameter_matchers/stub_matcher.rb +27 -0
  163. data/test/unit/parameter_matchers/yaml_equivalent_test.rb +25 -0
  164. data/test/unit/parameters_matcher_test.rb +121 -0
  165. data/test/unit/return_values_test.rb +63 -0
  166. data/test/unit/sequence_test.rb +104 -0
  167. data/test/unit/single_return_value_test.rb +14 -0
  168. data/test/unit/single_yield_test.rb +18 -0
  169. data/test/unit/state_machine_test.rb +98 -0
  170. data/test/unit/string_inspect_test.rb +11 -0
  171. data/test/unit/yield_parameters_test.rb +93 -0
  172. metadata +240 -0
@@ -0,0 +1,42 @@
1
+ require 'mocha/parameter_matchers/base'
2
+
3
+ module Mocha
4
+
5
+ module ParameterMatchers
6
+
7
+ # :call-seq: Not(parameter_matcher) -> parameter_matcher
8
+ #
9
+ # Matches if +parameter_matcher+ does not match.
10
+ # object = mock()
11
+ # object.expects(:method_1).with(Not(includes(1)))
12
+ # object.method_1([0, 2, 3])
13
+ # # no error raised
14
+ #
15
+ # object = mock()
16
+ # object.expects(:method_1).with(Not(includes(1)))
17
+ # object.method_1([0, 1, 2, 3])
18
+ # # error raised, because method_1 was not called with object not including 1
19
+ def Not(matcher)
20
+ Not.new(matcher)
21
+ end
22
+
23
+ class Not < Base # :nodoc:
24
+
25
+ def initialize(matcher)
26
+ @matcher = matcher
27
+ end
28
+
29
+ def matches?(available_parameters)
30
+ parameter = available_parameters.shift
31
+ !@matcher.matches?([parameter])
32
+ end
33
+
34
+ def mocha_inspect
35
+ "Not(#{@matcher.mocha_inspect})"
36
+ end
37
+
38
+ end
39
+
40
+ end
41
+
42
+ end
@@ -0,0 +1,15 @@
1
+ require 'mocha/parameter_matchers/equals'
2
+
3
+ module Mocha
4
+
5
+ module ObjectMethods
6
+ def to_matcher # :nodoc:
7
+ Mocha::ParameterMatchers::Equals.new(self)
8
+ end
9
+ end
10
+
11
+ end
12
+
13
+ class Object
14
+ include Mocha::ObjectMethods
15
+ end
@@ -0,0 +1,55 @@
1
+ module Mocha
2
+
3
+ module ParameterMatchers
4
+
5
+ # :call-seq: optionally(*parameter_matchers) -> parameter_matcher
6
+ #
7
+ # Matches optional parameters if available.
8
+ # object = mock()
9
+ # object.expects(:method_1).with(1, 2, optionally(3, 4))
10
+ # object.method_1(1, 2)
11
+ # # no error raised
12
+ #
13
+ # object = mock()
14
+ # object.expects(:method_1).with(1, 2, optionally(3, 4))
15
+ # object.method_1(1, 2, 3)
16
+ # # no error raised
17
+ #
18
+ # object = mock()
19
+ # object.expects(:method_1).with(1, 2, optionally(3, 4))
20
+ # object.method_1(1, 2, 3, 4)
21
+ # # no error raised
22
+ #
23
+ # object = mock()
24
+ # object.expects(:method_1).with(1, 2, optionally(3, 4))
25
+ # object.method_1(1, 2, 3, 5)
26
+ # # error raised, because optional parameters did not match
27
+ def optionally(*matchers)
28
+ Optionally.new(*matchers)
29
+ end
30
+
31
+ class Optionally < Base # :nodoc:
32
+
33
+ def initialize(*parameters)
34
+ @matchers = parameters.map { |parameter| parameter.to_matcher }
35
+ end
36
+
37
+ def matches?(available_parameters)
38
+ index = 0
39
+ while (available_parameters.length > 0) && (index < @matchers.length) do
40
+ matcher = @matchers[index]
41
+ return false unless matcher.matches?(available_parameters)
42
+ index += 1
43
+ end
44
+ return true
45
+ end
46
+
47
+ def mocha_inspect
48
+ "optionally(#{@matchers.map { |matcher| matcher.mocha_inspect }.join(", ") })"
49
+ end
50
+
51
+ end
52
+
53
+ end
54
+
55
+ end
@@ -0,0 +1,44 @@
1
+ require 'mocha/parameter_matchers/base'
2
+
3
+ module Mocha
4
+
5
+ module ParameterMatchers
6
+
7
+ # :call-seq: regexp_matches(regular_expression) -> parameter_matcher
8
+ #
9
+ # Matches any object that matches +regular_expression+.
10
+ # object = mock()
11
+ # object.expects(:method_1).with(regexp_matches(/e/))
12
+ # object.method_1('hello')
13
+ # # no error raised
14
+ #
15
+ # object = mock()
16
+ # object.expects(:method_1).with(regexp_matches(/a/))
17
+ # object.method_1('hello')
18
+ # # error raised, because method_1 was not called with a parameter that matched the
19
+ # # regular expression
20
+ def regexp_matches(regexp)
21
+ RegexpMatches.new(regexp)
22
+ end
23
+
24
+ class RegexpMatches < Base # :nodoc:
25
+
26
+ def initialize(regexp)
27
+ @regexp = regexp
28
+ end
29
+
30
+ def matches?(available_parameters)
31
+ parameter = available_parameters.shift
32
+ return false unless parameter.respond_to?(:=~)
33
+ parameter =~ @regexp
34
+ end
35
+
36
+ def mocha_inspect
37
+ "regexp_matches(#{@regexp.mocha_inspect})"
38
+ end
39
+
40
+ end
41
+
42
+ end
43
+
44
+ end
@@ -0,0 +1,43 @@
1
+ require 'mocha/parameter_matchers/base'
2
+ require 'yaml'
3
+
4
+ module Mocha
5
+
6
+ module ParameterMatchers
7
+
8
+ # :call-seq: responds_with(message, result) -> parameter_matcher
9
+ #
10
+ # Matches any object that responds to +message+ with +result+. To put it another way, it tests the quack, not the duck.
11
+ # object = mock()
12
+ # object.expects(:method_1).with(responds_with(:upcase, "FOO"))
13
+ # object.method_1("foo")
14
+ # # no error raised, because "foo".upcase == "FOO"
15
+ #
16
+ # object = mock()
17
+ # object.expects(:method_1).with(responds_with(:upcase, "BAR"))
18
+ # object.method_1("foo")
19
+ # # error raised, because "foo".upcase != "BAR"
20
+ def responds_with(message, result)
21
+ RespondsWith.new(message, result)
22
+ end
23
+
24
+ class RespondsWith < Base # :nodoc:
25
+
26
+ def initialize(message, result)
27
+ @message, @result = message, result
28
+ end
29
+
30
+ def matches?(available_parameters)
31
+ parameter = available_parameters.shift
32
+ parameter.__send__(@message) == @result
33
+ end
34
+
35
+ def mocha_inspect
36
+ "responds_with(#{@message.mocha_inspect}, #{@result.mocha_inspect})"
37
+ end
38
+
39
+ end
40
+
41
+ end
42
+
43
+ end
@@ -0,0 +1,43 @@
1
+ require 'mocha/parameter_matchers/base'
2
+ require 'yaml'
3
+
4
+ module Mocha
5
+
6
+ module ParameterMatchers
7
+
8
+ # :call-seq: yaml_equivalent(object) -> parameter_matcher
9
+ #
10
+ # Matches any YAML that represents the specified +object+
11
+ # object = mock()
12
+ # object.expects(:method_1).with(yaml_equivalent(1, 2, 3))
13
+ # object.method_1("--- \n- 1\n- 2\n- 3\n")
14
+ # # no error raised
15
+ #
16
+ # object = mock()
17
+ # object.expects(:method_1).with(yaml_equivalent(1, 2, 3))
18
+ # object.method_1("--- \n- 1\n- 2\n")
19
+ # # error raised, because method_1 was not called with YAML representing the specified Array
20
+ def yaml_equivalent(object)
21
+ YamlEquivalent.new(object)
22
+ end
23
+
24
+ class YamlEquivalent < Base # :nodoc:
25
+
26
+ def initialize(object)
27
+ @object = object
28
+ end
29
+
30
+ def matches?(available_parameters)
31
+ parameter = available_parameters.shift
32
+ @object == YAML.load(parameter)
33
+ end
34
+
35
+ def mocha_inspect
36
+ "yaml_equivalent(#{@object.mocha_inspect})"
37
+ end
38
+
39
+ end
40
+
41
+ end
42
+
43
+ end
@@ -0,0 +1,37 @@
1
+ require 'mocha/inspect'
2
+ require 'mocha/parameter_matchers'
3
+
4
+ module Mocha
5
+
6
+ class ParametersMatcher
7
+
8
+ def initialize(expected_parameters = [ParameterMatchers::AnyParameters.new], &matching_block)
9
+ @expected_parameters, @matching_block = expected_parameters, matching_block
10
+ end
11
+
12
+ def match?(actual_parameters = [])
13
+ if @matching_block
14
+ return @matching_block.call(*actual_parameters)
15
+ else
16
+ return parameters_match?(actual_parameters)
17
+ end
18
+ end
19
+
20
+ def parameters_match?(actual_parameters)
21
+ matchers.all? { |matcher| matcher.matches?(actual_parameters) } && (actual_parameters.length == 0)
22
+ end
23
+
24
+ def mocha_inspect
25
+ signature = matchers.mocha_inspect
26
+ signature = signature.gsub(/^\[|\]$/, '')
27
+ signature = signature.gsub(/^\{|\}$/, '') if matchers.length == 1
28
+ "(#{signature})"
29
+ end
30
+
31
+ def matchers
32
+ @expected_parameters.map { |parameter| parameter.to_matcher }
33
+ end
34
+
35
+ end
36
+
37
+ end
@@ -0,0 +1,28 @@
1
+ require 'mocha/inspect'
2
+
3
+ module Mocha
4
+
5
+ class PrettyParameters
6
+
7
+ def initialize(params)
8
+ @params = params
9
+ @params_string = params.mocha_inspect
10
+ end
11
+
12
+ def pretty
13
+ remove_outer_array_braces!
14
+ remove_outer_hash_braces!
15
+ @params_string
16
+ end
17
+
18
+ def remove_outer_array_braces!
19
+ @params_string = @params_string.gsub(/^\[|\]$/, '')
20
+ end
21
+
22
+ def remove_outer_hash_braces!
23
+ @params_string = @params_string.gsub(/^\{|\}$/, '') if @params.length == 1
24
+ end
25
+
26
+ end
27
+
28
+ end
@@ -0,0 +1,31 @@
1
+ require 'mocha/single_return_value'
2
+
3
+ module Mocha # :nodoc:
4
+
5
+ class ReturnValues # :nodoc:
6
+
7
+ def self.build(*values)
8
+ new(*values.map { |value| SingleReturnValue.new(value) })
9
+ end
10
+
11
+ attr_accessor :values
12
+
13
+ def initialize(*values)
14
+ @values = values
15
+ end
16
+
17
+ def next
18
+ case @values.length
19
+ when 0 then nil
20
+ when 1 then @values.first.evaluate
21
+ else @values.shift.evaluate
22
+ end
23
+ end
24
+
25
+ def +(other)
26
+ self.class.new(*(@values + other.values))
27
+ end
28
+
29
+ end
30
+
31
+ end
@@ -0,0 +1,42 @@
1
+ module Mocha # :nodoc:
2
+
3
+ class Sequence
4
+
5
+ class InSequenceOrderingConstraint
6
+
7
+ def initialize(sequence, index)
8
+ @sequence, @index = sequence, index
9
+ end
10
+
11
+ def allows_invocation_now?
12
+ @sequence.satisfied_to_index?(@index)
13
+ end
14
+
15
+ def mocha_inspect
16
+ "in sequence #{@sequence.mocha_inspect}"
17
+ end
18
+
19
+ end
20
+
21
+ def initialize(name)
22
+ @name = name
23
+ @expectations = []
24
+ end
25
+
26
+ def constrain_as_next_in_sequence(expectation)
27
+ index = @expectations.length
28
+ @expectations << expectation
29
+ expectation.add_ordering_constraint(InSequenceOrderingConstraint.new(self, index))
30
+ end
31
+
32
+ def satisfied_to_index?(index)
33
+ @expectations[0...index].all? { |expectation| expectation.satisfied? }
34
+ end
35
+
36
+ def mocha_inspect
37
+ "#{@name.mocha_inspect}"
38
+ end
39
+
40
+ end
41
+
42
+ end
@@ -0,0 +1,17 @@
1
+ require 'mocha/is_a'
2
+
3
+ module Mocha # :nodoc:
4
+
5
+ class SingleReturnValue # :nodoc:
6
+
7
+ def initialize(value)
8
+ @value = value
9
+ end
10
+
11
+ def evaluate
12
+ @value
13
+ end
14
+
15
+ end
16
+
17
+ end
@@ -0,0 +1,18 @@
1
+ module Mocha # :nodoc:
2
+
3
+ class SingleYield # :nodoc:
4
+
5
+ attr_reader :parameters
6
+
7
+ def initialize(*parameters)
8
+ @parameters = parameters
9
+ end
10
+
11
+ def each
12
+ yield(@parameters)
13
+ end
14
+
15
+ end
16
+
17
+ end
18
+
@@ -0,0 +1 @@
1
+ require 'mocha/api'
@@ -0,0 +1,91 @@
1
+ module Mocha # :nodoc:
2
+
3
+ # A state machine that is used to constrain the order of invocations.
4
+ # An invocation can be constrained to occur when a state is, or is_not, active.
5
+ class StateMachine
6
+
7
+ class State # :nodoc:
8
+
9
+ def initialize(state_machine, state)
10
+ @state_machine, @state = state_machine, state
11
+ end
12
+
13
+ def activate
14
+ @state_machine.current_state = @state
15
+ end
16
+
17
+ def active?
18
+ @state_machine.current_state == @state
19
+ end
20
+
21
+ def mocha_inspect
22
+ "#{@state_machine.name} is #{@state.mocha_inspect}"
23
+ end
24
+
25
+ end
26
+
27
+ class StatePredicate # :nodoc:
28
+
29
+ def initialize(state_machine, state)
30
+ @state_machine, @state = state_machine, state
31
+ end
32
+
33
+ def active?
34
+ @state_machine.current_state != @state
35
+ end
36
+
37
+ def mocha_inspect
38
+ "#{@state_machine.name} is not #{@state.mocha_inspect}"
39
+ end
40
+
41
+ end
42
+
43
+ attr_reader :name # :nodoc:
44
+
45
+ attr_accessor :current_state # :nodoc:
46
+
47
+ def initialize(name) # :nodoc:
48
+ @name = name
49
+ @current_state = nil
50
+ end
51
+
52
+ # :call-seq: starts_as(initial_state) -> state_machine
53
+ #
54
+ # Put the +state_machine+ into the +initial_state+.
55
+ def starts_as(initial_state)
56
+ become(initial_state)
57
+ self
58
+ end
59
+
60
+ # :call-seq: become(next_state)
61
+ #
62
+ # Put the +state_machine+ into the +next_state+.
63
+ def become(next_state)
64
+ @current_state = next_state
65
+ end
66
+
67
+ # :call-seq: is(state)
68
+ #
69
+ # Determines whether the +state_machine+ is in the specified +state+.
70
+ def is(state)
71
+ State.new(self, state)
72
+ end
73
+
74
+ # :call-seq: is_not(state)
75
+ #
76
+ # Determines whether the +state_machine+ is not in the specified +state+.
77
+ def is_not(state)
78
+ StatePredicate.new(self, state)
79
+ end
80
+
81
+ def mocha_inspect # :nodoc:
82
+ if @current_state
83
+ "#{@name} is #{@current_state.mocha_inspect}"
84
+ else
85
+ "#{@name} has no current state"
86
+ end
87
+ end
88
+
89
+ end
90
+
91
+ end