rspec 0.7.5.1 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (194) hide show
  1. data/CHANGES +60 -1
  2. data/EXAMPLES.rd +38 -19
  3. data/MIT-LICENSE +1 -1
  4. data/README +24 -17
  5. data/RELEASE-PLAN +117 -0
  6. data/Rakefile +24 -18
  7. data/TODO.0.8.0 +5 -0
  8. data/examples/auto_spec_name_generation_example.rb +18 -0
  9. data/examples/custom_expectation_matchers.rb +53 -0
  10. data/examples/dynamic_spec.rb +9 -0
  11. data/examples/io_processor_spec.rb +2 -2
  12. data/examples/mocking_example.rb +4 -4
  13. data/examples/partial_mock_example.rb +2 -2
  14. data/examples/predicate_example.rb +2 -2
  15. data/examples/stack_spec.rb +32 -36
  16. data/examples/stubbing_example.rb +19 -19
  17. data/examples/test_case_spec.rb +6 -6
  18. data/lib/spec.rb +3 -0
  19. data/lib/spec/callback.rb +8 -0
  20. data/lib/spec/callback/extensions/object.rb +4 -0
  21. data/lib/spec/deprecated.rb +3 -0
  22. data/lib/spec/expectations.rb +44 -17
  23. data/lib/spec/expectations/extensions.rb +1 -2
  24. data/lib/spec/expectations/extensions/object.rb +78 -130
  25. data/lib/spec/expectations/extensions/string_and_symbol.rb +17 -0
  26. data/lib/spec/expectations/handler.rb +47 -0
  27. data/lib/spec/expectations/should/base.rb +32 -29
  28. data/lib/spec/expectations/should/change.rb +1 -1
  29. data/lib/spec/expectations/should/have.rb +9 -17
  30. data/lib/spec/expectations/should/not.rb +54 -56
  31. data/lib/spec/expectations/should/should.rb +59 -65
  32. data/lib/spec/expectations/sugar.rb +27 -4
  33. data/lib/spec/matchers.rb +160 -0
  34. data/lib/spec/matchers/be.rb +161 -0
  35. data/lib/spec/matchers/be_close.rb +37 -0
  36. data/lib/spec/matchers/change.rb +120 -0
  37. data/lib/spec/matchers/eql.rb +43 -0
  38. data/lib/spec/matchers/equal.rb +43 -0
  39. data/lib/spec/matchers/has.rb +44 -0
  40. data/lib/spec/matchers/have.rb +140 -0
  41. data/lib/spec/matchers/include.rb +50 -0
  42. data/lib/spec/matchers/match.rb +41 -0
  43. data/lib/spec/matchers/raise_error.rb +100 -0
  44. data/lib/spec/matchers/respond_to.rb +35 -0
  45. data/lib/spec/matchers/satisfy.rb +47 -0
  46. data/lib/spec/matchers/throw_symbol.rb +75 -0
  47. data/lib/spec/mocks.rb +224 -1
  48. data/lib/spec/mocks/argument_expectation.rb +16 -2
  49. data/lib/spec/mocks/error_generator.rb +5 -3
  50. data/lib/spec/mocks/errors.rb +2 -2
  51. data/lib/spec/mocks/extensions/object.rb +1 -1
  52. data/lib/spec/mocks/message_expectation.rb +29 -19
  53. data/lib/spec/mocks/{mock_methods.rb → methods.rb} +5 -5
  54. data/lib/spec/mocks/mock.rb +2 -2
  55. data/lib/spec/mocks/mock_handler.rb +81 -68
  56. data/lib/spec/rake/spectask.rb +7 -12
  57. data/lib/spec/rake/verify_rcov.rb +1 -1
  58. data/lib/spec/runner.rb +117 -0
  59. data/lib/spec/runner/command_line.rb +8 -5
  60. data/lib/spec/runner/context.rb +13 -37
  61. data/lib/spec/runner/context_eval.rb +4 -3
  62. data/lib/spec/runner/context_runner.rb +7 -4
  63. data/lib/spec/runner/drb_command_line.rb +1 -1
  64. data/lib/spec/runner/execution_context.rb +3 -11
  65. data/lib/spec/runner/extensions/kernel.rb +7 -5
  66. data/lib/spec/runner/extensions/object.rb +4 -1
  67. data/lib/spec/runner/formatter/base_text_formatter.rb +11 -3
  68. data/lib/spec/runner/formatter/html_formatter.rb +21 -10
  69. data/lib/spec/runner/heckle_runner.rb +24 -8
  70. data/lib/spec/runner/heckle_runner_win.rb +10 -0
  71. data/lib/spec/runner/option_parser.rb +58 -13
  72. data/lib/spec/runner/spec_matcher.rb +22 -29
  73. data/lib/spec/runner/spec_parser.rb +1 -0
  74. data/lib/spec/runner/specification.rb +36 -22
  75. data/lib/spec/translator.rb +87 -0
  76. data/lib/spec/version.rb +16 -7
  77. data/spec/spec/callback/callback_container_spec.rb +27 -0
  78. data/spec/spec/callback/module_spec.rb +37 -0
  79. data/spec/spec/callback/object_spec.rb +90 -0
  80. data/spec/spec/callback/object_with_class_callback_spec.rb +19 -0
  81. data/spec/spec/expectations/differs/default_spec.rb +107 -0
  82. data/spec/spec/expectations/extensions/object_spec.rb +46 -0
  83. data/spec/spec/expectations/fail_with_spec.rb +71 -0
  84. data/spec/spec/expectations/should/should_==_spec.rb +19 -0
  85. data/spec/spec/expectations/should/should_=~_spec.rb +13 -0
  86. data/spec/spec/expectations/should/should_be_a_kind_of_spec.rb +21 -0
  87. data/spec/spec/expectations/should/should_be_an_instance_of_spec.rb +30 -0
  88. data/spec/spec/expectations/should/should_be_arbitrary_predicate_spec.rb +81 -0
  89. data/spec/spec/expectations/should/should_be_close_spec.rb +18 -0
  90. data/spec/spec/expectations/should/should_be_comparison_operator_spec.rb +44 -0
  91. data/spec/spec/expectations/should/should_be_false_spec.rb +39 -0
  92. data/spec/spec/expectations/should/should_be_spec.rb +11 -0
  93. data/spec/spec/expectations/should/should_be_true_spec.rb +27 -0
  94. data/spec/spec/expectations/should/should_change_spec.rb +184 -0
  95. data/spec/spec/expectations/should/should_eql_spec.rb +11 -0
  96. data/spec/spec/expectations/should/should_equal_spec.rb +11 -0
  97. data/spec/spec/expectations/should/should_have_at_least_spec.rb +53 -0
  98. data/spec/spec/expectations/should/should_have_at_most_spec.rb +45 -0
  99. data/spec/spec/expectations/should/should_have_key_spec.rb +21 -0
  100. data/spec/spec/expectations/should/should_have_spec.rb +64 -0
  101. data/spec/spec/expectations/should/should_include_spec.rb +59 -0
  102. data/spec/spec/expectations/should/should_match_spec.rb +25 -0
  103. data/spec/spec/expectations/should/should_not_==_spec.rb +15 -0
  104. data/spec/spec/expectations/should/should_not_be_a_kind_of_spec.rb +21 -0
  105. data/spec/spec/expectations/should/should_not_be_an_instance_of_spec.rb +11 -0
  106. data/spec/spec/expectations/should/should_not_be_arbitrary_predicate_spec.rb +68 -0
  107. data/spec/spec/expectations/should/should_not_be_spec.rb +11 -0
  108. data/spec/spec/expectations/should/should_not_change_spec.rb +24 -0
  109. data/spec/spec/expectations/should/should_not_eql_spec.rb +11 -0
  110. data/spec/spec/expectations/should/should_not_equal_spec.rb +11 -0
  111. data/spec/spec/expectations/should/should_not_have_key_spec.rb +15 -0
  112. data/spec/spec/expectations/should/should_not_include_spec.rb +58 -0
  113. data/spec/spec/expectations/should/should_not_match_spec.rb +11 -0
  114. data/spec/spec/expectations/should/should_not_raise_spec.rb +75 -0
  115. data/spec/spec/expectations/should/should_not_respond_to_spec.rb +15 -0
  116. data/spec/spec/expectations/should/should_not_throw_spec.rb +35 -0
  117. data/spec/spec/expectations/should/should_raise_spec.rb +66 -0
  118. data/spec/spec/expectations/should/should_respond_to_spec.rb +15 -0
  119. data/spec/spec/expectations/should/should_satisfy_spec.rb +35 -0
  120. data/spec/spec/expectations/should/should_throw_spec.rb +27 -0
  121. data/spec/spec/matchers/be_close_spec.rb +33 -0
  122. data/spec/spec/matchers/be_spec.rb +182 -0
  123. data/spec/spec/matchers/change_spec.rb +232 -0
  124. data/spec/spec/matchers/description_generation_spec.rb +147 -0
  125. data/spec/spec/matchers/eql_spec.rb +41 -0
  126. data/spec/spec/matchers/equal_spec.rb +41 -0
  127. data/spec/spec/matchers/handler_spec.rb +75 -0
  128. data/spec/spec/matchers/has_spec.rb +37 -0
  129. data/spec/spec/matchers/have_spec.rb +259 -0
  130. data/spec/spec/matchers/include_spec.rb +33 -0
  131. data/spec/spec/matchers/match_spec.rb +37 -0
  132. data/spec/spec/matchers/matcher_methods_spec.rb +85 -0
  133. data/spec/spec/matchers/raise_error_spec.rb +147 -0
  134. data/spec/spec/matchers/respond_to_spec.rb +30 -0
  135. data/spec/spec/matchers/satisfy_spec.rb +36 -0
  136. data/spec/spec/matchers/throw_symbol_spec.rb +59 -0
  137. data/spec/spec/mocks/any_number_of_times_spec.rb +34 -0
  138. data/spec/spec/mocks/at_least_spec.rb +97 -0
  139. data/spec/spec/mocks/at_most_spec.rb +97 -0
  140. data/spec/spec/mocks/bug_report_7611_spec.rb +19 -0
  141. data/spec/spec/mocks/bug_report_7805_spec.rb +22 -0
  142. data/spec/spec/mocks/bug_report_8165_spec.rb +31 -0
  143. data/spec/spec/mocks/bug_report_8302_spec.rb +26 -0
  144. data/spec/spec/mocks/failing_mock_argument_constraints_spec.rb +74 -0
  145. data/spec/spec/mocks/mock_ordering_spec.rb +80 -0
  146. data/spec/spec/mocks/mock_spec.rb +407 -0
  147. data/spec/spec/mocks/multiple_return_value_spec.rb +113 -0
  148. data/spec/spec/mocks/null_object_mock_spec.rb +40 -0
  149. data/spec/spec/mocks/once_counts_spec.rb +56 -0
  150. data/spec/spec/mocks/options_hash_spec.rb +31 -0
  151. data/spec/spec/mocks/partial_mock_spec.rb +52 -0
  152. data/spec/spec/mocks/partial_mock_using_mocks_directly_spec.rb +64 -0
  153. data/spec/spec/mocks/passing_mock_argument_constraints_spec.rb +92 -0
  154. data/spec/spec/mocks/precise_counts_spec.rb +56 -0
  155. data/spec/spec/mocks/record_messages_spec.rb +26 -0
  156. data/spec/spec/mocks/stub_spec.rb +159 -0
  157. data/spec/spec/mocks/twice_counts_spec.rb +67 -0
  158. data/spec/spec/runner/command_line_spec.rb +32 -0
  159. data/spec/spec/runner/context_matching_spec.rb +28 -0
  160. data/spec/spec/runner/context_runner_spec.rb +100 -0
  161. data/spec/spec/runner/context_spec.rb +405 -0
  162. data/spec/spec/runner/drb_command_line_spec.rb +74 -0
  163. data/spec/spec/runner/execution_context_spec.rb +52 -0
  164. data/spec/spec/runner/formatter/html_formatter_spec.rb +40 -0
  165. data/spec/spec/runner/formatter/progress_bar_formatter_dry_run_spec.rb +21 -0
  166. data/spec/spec/runner/formatter/progress_bar_formatter_failure_dump_spec.rb +36 -0
  167. data/spec/spec/runner/formatter/progress_bar_formatter_spec.rb +78 -0
  168. data/spec/spec/runner/formatter/rdoc_formatter_dry_run_spec.rb +18 -0
  169. data/spec/spec/runner/formatter/rdoc_formatter_spec.rb +41 -0
  170. data/spec/spec/runner/formatter/specdoc_formatter_dry_run_spec.rb +21 -0
  171. data/spec/spec/runner/formatter/specdoc_formatter_spec.rb +46 -0
  172. data/spec/spec/runner/heckle_runner_spec.rb +63 -0
  173. data/spec/spec/runner/heckler_spec.rb +14 -0
  174. data/spec/spec/runner/kernel_ext_spec.rb +16 -0
  175. data/spec/spec/runner/noisy_backtrace_tweaker_spec.rb +45 -0
  176. data/spec/spec/runner/object_ext_spec.rb +11 -0
  177. data/spec/spec/runner/option_parser_spec.rb +269 -0
  178. data/spec/spec/runner/quiet_backtrace_tweaker_spec.rb +47 -0
  179. data/spec/spec/runner/reporter_spec.rb +126 -0
  180. data/spec/spec/runner/spec_matcher_spec.rb +107 -0
  181. data/spec/spec/runner/spec_name_generation_spec.rb +102 -0
  182. data/spec/spec/runner/spec_parser_spec.rb +37 -0
  183. data/spec/spec/runner/specification_class_spec.rb +72 -0
  184. data/spec/spec/runner/specification_instance_spec.rb +160 -0
  185. data/spec/spec/runner/specification_should_raise_spec.rb +136 -0
  186. data/spec/spec/spec_classes.rb +102 -0
  187. data/spec/spec/translator_spec.rb +79 -0
  188. data/spec/spec_helper.rb +35 -0
  189. metadata +141 -9
  190. data/bin/drbspec +0 -3
  191. data/lib/spec/expectations/diff.rb +0 -28
  192. data/lib/spec/expectations/extensions/numeric.rb +0 -19
  193. data/lib/spec/expectations/extensions/string.rb +0 -22
  194. data/lib/spec/expectations/message_builder.rb +0 -13
@@ -1,32 +1,25 @@
1
- class SpecMatcher
1
+ module Spec
2
+ module Runner
3
+ class SpecMatcher
2
4
 
3
- def initialize(context_and_or_spec_name, context_name)
4
- @context_name = context_name
5
- @name_to_match = context_and_or_spec_name
5
+ attr_writer :spec_desc
6
+ def initialize(context_desc, spec_desc=nil)
7
+ @context_desc = context_desc
8
+ @spec_desc = spec_desc
9
+ end
10
+
11
+ def matches?(desc)
12
+ desc =~ /(^#{context_regexp} #{spec_regexp}$|^#{context_regexp}$|^#{spec_regexp}$)/
13
+ end
14
+
15
+ private
16
+ def context_regexp
17
+ Regexp.escape(@context_desc)
18
+ end
19
+
20
+ def spec_regexp
21
+ Regexp.escape(@spec_desc)
22
+ end
23
+ end
6
24
  end
7
-
8
- def matches?(spec_name)
9
- return true if matches_context? && (matches_spec?(spec_name) || context_only?)
10
- return true if matches_spec?(spec_name) && spec_only?(spec_name)
11
- return false
12
- end
13
-
14
- private
15
-
16
- def spec_only? spec
17
- @name_to_match == spec
18
- end
19
-
20
- def context_only?
21
- @name_to_match == @context_name
22
- end
23
-
24
- def matches_context?
25
- @name_to_match =~ /^#{Regexp.escape(@context_name)}\b/
26
- end
27
-
28
- def matches_spec?(spec_name)
29
- @name_to_match =~ /\b#{Regexp.escape(spec_name)}$/
30
- end
31
-
32
25
  end
@@ -1,5 +1,6 @@
1
1
  module Spec
2
2
  module Runner
3
+ # Parses a spec file and finds the nearest spec for a given line number.
3
4
  class SpecParser
4
5
  def spec_name_for(io, line_number)
5
6
  source = io.read
@@ -1,27 +1,28 @@
1
1
  module Spec
2
2
  module Runner
3
3
  class Specification
4
- module ClassMethods
5
- attr_accessor :current
4
+
5
+ class << self
6
+ attr_accessor :current, :generated_description
6
7
  protected :current=
7
8
 
8
9
  callback_events :before_setup, :after_teardown
9
10
  end
10
- extend ClassMethods
11
11
 
12
- attr_reader :command
12
+ attr_reader :spec_block
13
13
  callback_events :before_setup, :after_teardown
14
14
 
15
- def initialize(name, opts={}, &block)
15
+ def initialize(name, opts={}, &spec_block)
16
16
  @from = caller(0)[3]
17
- @name = name
17
+ @description = name
18
18
  @options = opts
19
- @command = block
19
+ @spec_block = spec_block
20
+ @description_generated_callback = lambda { |desc| @generated_description = desc }
20
21
  end
21
22
 
22
23
  def run(reporter, setup_block, teardown_block, dry_run, execution_context)
23
- reporter.spec_started(@name) if reporter
24
- return reporter.spec_finished(@name) if dry_run
24
+ reporter.spec_started(name) if reporter
25
+ return reporter.spec_finished(name) if dry_run
25
26
 
26
27
  errors = []
27
28
  begin
@@ -34,14 +35,23 @@ module Spec
34
35
  end
35
36
 
36
37
  SpecShouldRaiseHandler.new(@from, @options).handle(errors)
37
- reporter.spec_finished(@name, errors.first, failure_location(setup_ok, spec_ok, teardown_ok)) if reporter
38
+ reporter.spec_finished(name, errors.first, failure_location(setup_ok, spec_ok, teardown_ok)) if reporter
38
39
  end
39
-
40
- def matches_matcher?(matcher)
41
- matcher.matches? @name
40
+
41
+ def matches?(matcher, description)
42
+ matcher.spec_desc = name
43
+ matcher.matches?(description)
42
44
  end
43
-
45
+
44
46
  private
47
+ def name
48
+ @description == :__generate_description ? generated_description : @description
49
+ end
50
+
51
+ def generated_description
52
+ @generated_description || "NAME NOT GENERATED"
53
+ end
54
+
45
55
  def setup_spec(execution_context, errors, &setup_block)
46
56
  notify_before_setup(errors)
47
57
  execution_context.instance_eval(&setup_block) if setup_block
@@ -52,11 +62,13 @@ module Spec
52
62
  end
53
63
 
54
64
  def execute_spec(execution_context, errors)
55
- execution_context.instance_eval(&command)
56
- return true
57
- rescue => e
58
- errors << e
59
- return false
65
+ begin
66
+ execution_context.instance_eval(&spec_block)
67
+ return true
68
+ rescue Exception => e
69
+ errors << e
70
+ return false
71
+ end
60
72
  end
61
73
 
62
74
  def teardown_spec(execution_context, errors, &teardown_block)
@@ -69,13 +81,13 @@ module Spec
69
81
  end
70
82
 
71
83
  def notify_before_setup(errors)
72
- self.class.send(:notify_callbacks, :before_setup, self, &append_errors(errors))
84
+ notify_class_callbacks(:before_setup, self, &append_errors(errors))
73
85
  notify_callbacks(:before_setup, self, &append_errors(errors))
74
86
  end
75
87
 
76
88
  def notify_after_teardown(errors)
77
89
  notify_callbacks(:after_teardown, self, &append_errors(errors))
78
- self.class.send(:notify_callbacks, :after_teardown, self, &append_errors(errors))
90
+ notify_class_callbacks(:after_teardown, self, &append_errors(errors))
79
91
  end
80
92
 
81
93
  def append_errors(errors)
@@ -83,16 +95,18 @@ module Spec
83
95
  end
84
96
 
85
97
  def set_current
98
+ Spec::Matchers.description_generated(&@description_generated_callback)
86
99
  self.class.send(:current=, self)
87
100
  end
88
101
 
89
102
  def clear_current
103
+ Spec::Matchers.unregister_callback(:description_generated, @description_generated_callback)
90
104
  self.class.send(:current=, nil)
91
105
  end
92
106
 
93
107
  def failure_location(setup_ok, spec_ok, teardown_ok)
94
108
  return 'setup' unless setup_ok
95
- return @name unless spec_ok
109
+ return name unless spec_ok
96
110
  return 'teardown' unless teardown_ok
97
111
  end
98
112
  end
@@ -0,0 +1,87 @@
1
+ require 'fileutils'
2
+
3
+ module Spec
4
+ class Translator
5
+ def translate_dir(from, to)
6
+ from = File.expand_path(from)
7
+ to = File.expand_path(to)
8
+ if File.directory?(from)
9
+ FileUtils.mkdir_p(to) unless File.directory?(to)
10
+ Dir["#{from}/*"].each do |sub_from|
11
+ path = sub_from[from.length+1..-1]
12
+ sub_to = File.join(to, path)
13
+ translate_dir(sub_from, sub_to)
14
+ end
15
+ else
16
+ translate_file(from, to)
17
+ end
18
+ end
19
+
20
+ def translate_file(from, to)
21
+ translation = ""
22
+ File.open(from) do |io|
23
+ io.each_line do |line|
24
+ translation << translate(line)
25
+ end
26
+ end
27
+ File.open(to, "w") do |io|
28
+ io.write(translation)
29
+ end
30
+ end
31
+
32
+ def translate(line)
33
+ return line if line =~ /(should_not|should)_receive/
34
+
35
+ if line =~ /(.*\.)(should_not|should)(?:_be)(?!_)(.*)/m
36
+ pre = $1
37
+ should = $2
38
+ post = $3
39
+ be_or_equal = post =~ /(<|>)/ ? "be" : "equal"
40
+
41
+ return "#{pre}#{should} #{be_or_equal}#{post}"
42
+ end
43
+
44
+ if line =~ /(.*\.)(should_not|should)_(?!not)(.*)/m
45
+ pre = $1
46
+ should = $2
47
+ post = $3
48
+
49
+ post.gsub!(/^raise/, 'raise_error')
50
+ post.gsub!(/^throw/, 'throw_symbol')
51
+
52
+ unless standard_matcher?(post)
53
+ post = "be_#{post}"
54
+ end
55
+
56
+ line = "#{pre}#{should} #{post}"
57
+ end
58
+
59
+ line
60
+ end
61
+
62
+ def standard_matcher?(matcher)
63
+ patterns = [
64
+ /^be/,
65
+ /^be_close/,
66
+ /^eql/,
67
+ /^equal/,
68
+ /^has/,
69
+ /^have/,
70
+ /^change/,
71
+ /^include/,
72
+ /^match/,
73
+ /^raise_error/,
74
+ /^respond_to/,
75
+ /^satisfy/,
76
+ /^throw_symbol/,
77
+ # Extra ones that we use in spec_helper
78
+ /^pass/,
79
+ /^fail/,
80
+ /^fail_with/,
81
+ ]
82
+ matched = patterns.detect{ |p| matcher =~ p }
83
+ !matched.nil?
84
+ end
85
+
86
+ end
87
+ end
@@ -1,16 +1,25 @@
1
1
  module Spec
2
2
  module VERSION
3
+ def self.build_tag
4
+ tag = "REL_" + [MAJOR, MINOR, TINY].join('_')
5
+ if defined?(RELEASE_CANDIDATE)
6
+ tag << "_" << RELEASE_CANDIDATE
7
+ end
8
+ tag
9
+ end
10
+
3
11
  unless defined? MAJOR
4
12
  MAJOR = 0
5
- MINOR = 7
6
- TINY = 5
7
- MINISCULE = 1
8
- # RANDOM_TOKEN: 0.0543628986724853
9
- REV = "$LastChangedRevision: 1395 $".match(/LastChangedRevision: (\d+)/)[1]
13
+ MINOR = 8
14
+ TINY = 0
15
+ # RELEASE_CANDIDATE = "RC1"
16
+
17
+ # RANDOM_TOKEN: 0.714915709821417
18
+ REV = "$LastChangedRevision: 1550 $".match(/LastChangedRevision: (\d+)/)[1]
10
19
 
11
- STRING = [MAJOR, MINOR, TINY, MINISCULE].join('.')
20
+ STRING = [MAJOR, MINOR, TINY].join('.')
12
21
  FULL_VERSION = "#{STRING} (r#{REV})"
13
- TAG = "REL_" + [MAJOR, MINOR, TINY, MINISCULE].join('_')
22
+ TAG = build_tag
14
23
 
15
24
  NAME = "RSpec"
16
25
  URL = "http://rspec.rubyforge.org/"
@@ -0,0 +1,27 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper.rb'
2
+
3
+ context "A CallbackContainer instance" do
4
+ setup do
5
+ @container = Callback::CallbackContainer.new
6
+ end
7
+
8
+ specify "should define and call callbacks" do
9
+ @container.define(:foo) {:bar}
10
+ @container.define(:foo) {:baz}
11
+ @container.notify(:foo).should == [:bar, :baz]
12
+ end
13
+
14
+ specify "should undefine callbacks" do
15
+ callback_to_undefine = @container.define(:foo) {:bar}
16
+ @container.define(:foo) {:baz}
17
+ @container.undefine(:foo, callback_to_undefine)
18
+ @container.notify(:foo).should == [:baz]
19
+ end
20
+
21
+ specify "should clear all callbacks" do
22
+ @container.define(:foo) {:bar}
23
+ @container.define(:baz) {1}
24
+ @container.clear
25
+ @container.notify(:foo).should == []
26
+ end
27
+ end
@@ -0,0 +1,37 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper.rb'
2
+
3
+ context "A Module" do
4
+ specify "should provide callback_events and notify_callbacks methods" do
5
+ the_class = Class.new do
6
+ callback_events :foo
7
+ end
8
+
9
+ the_obj = the_class.new
10
+ the_obj.foo { :bar }
11
+ the_obj.notify_callbacks(:foo).should == [:bar]
12
+ end
13
+
14
+ specify "should support defining multiple callback_events with one call to callback_events" do
15
+ the_class = Class.new do
16
+ callback_events :foo, :bar
17
+ end
18
+
19
+ the_obj = the_class.new
20
+ the_obj.foo { 1 }
21
+ the_obj.bar { 2 }
22
+ the_obj.notify_callbacks(:foo).should == [1]
23
+ the_obj.notify_callbacks(:bar).should == [2]
24
+ end
25
+
26
+ specify "should provide unregister_callback method" do
27
+ the_class = Class.new do
28
+ callback_events :foo
29
+ end
30
+
31
+ the_obj = the_class.new
32
+ bar_proc = proc {:bar}
33
+ the_obj.foo &bar_proc
34
+ the_obj.unregister_callback(:foo, bar_proc)
35
+ the_obj.notify_callbacks(:foo).should == []
36
+ end
37
+ end
@@ -0,0 +1,90 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper.rb'
2
+
3
+ context "An Object" do
4
+ setup do
5
+ @callback_object = Object.new
6
+ end
7
+
8
+ specify "should be defined as a block and notified" do
9
+ specify_registration_and_notification do |callback_key, expected_callback|
10
+ @callback_object.register_callback(callback_key, &expected_callback)
11
+ end
12
+ end
13
+
14
+ specify "should be defined as a proc and notified" do
15
+ specify_registration_and_notification do |callback_key, expected_callback|
16
+ @callback_object.register_callback(callback_key, expected_callback)
17
+ end
18
+ end
19
+
20
+ specify "define should require callback with the call method" do
21
+ proc do
22
+ specify_registration_and_notification do |callback_key, expected_callback|
23
+ @callback_object.register_callback(callback_key)
24
+ end
25
+ end.should_raise(RuntimeError, "You must define the callback that accepts the call method.")
26
+ end
27
+
28
+ specify "should undefine a proc" do
29
+ specify_unregistration do |callback_key, callback|
30
+ @callback_object.unregister_callback callback_key, callback
31
+ end
32
+ end
33
+
34
+ specify "undefine should require callback with the call method" do
35
+ proc do
36
+ specify_unregistration do |callback_key, expected_callback|
37
+ @callback_object.unregister_callback(callback_key, nil)
38
+ end
39
+ end.should_raise(RuntimeError, "You may only undefine callbacks that use the call method.")
40
+ end
41
+
42
+ specify "should handle errors" do
43
+ @callback_object.register_callback(:error_callback) do
44
+ raise "First Error"
45
+ end
46
+
47
+ @callback_object.register_callback(:error_callback) do
48
+ raise "Second Error"
49
+ end
50
+
51
+ error_messages = []
52
+ @callback_object.notify_callbacks(:error_callback) do |e|
53
+ error_messages << e.message
54
+ end
55
+
56
+ error_messages.should_eql ["First Error", "Second Error"]
57
+ end
58
+
59
+ specify "should not fail with nothing to notify" do
60
+ @callback_object.notify_callbacks(:foobar, :argument)
61
+ end
62
+
63
+ protected
64
+ def specify_registration_and_notification
65
+ callback_key = :create
66
+ passed_callback_argument = nil
67
+ expected_callback = proc do |callback_argument|
68
+ passed_callback_argument = callback_argument
69
+ end
70
+
71
+ returned_callback = yield(callback_key, expected_callback)
72
+ returned_callback.should_equal expected_callback
73
+
74
+ expected_argument = Object.new
75
+ @callback_object.notify_callbacks(callback_key, expected_argument)
76
+ passed_callback_argument.should_equal expected_argument
77
+ end
78
+
79
+ def specify_unregistration
80
+ callback_key = :create
81
+ callback_called = false
82
+ callback = @callback_object.register_callback(callback_key) do
83
+ callback_called = true
84
+ end
85
+
86
+ yield(callback_key, callback)
87
+ @callback_object.notify_callbacks(callback_key)
88
+ callback_called.should_equal false
89
+ end
90
+ end