rspec 0.7.5.1 → 0.8.0

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 (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