micronaut 0.2.9

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 (79) hide show
  1. data/History.txt +15 -0
  2. data/LICENSE +45 -0
  3. data/README.markdown +66 -0
  4. data/RSPEC-LICENSE +23 -0
  5. data/Rakefile +78 -0
  6. data/VERSION.yml +4 -0
  7. data/bin/micronaut +4 -0
  8. data/examples/example_helper.rb +54 -0
  9. data/examples/lib/micronaut/behaviour_example.rb +351 -0
  10. data/examples/lib/micronaut/configuration_example.rb +133 -0
  11. data/examples/lib/micronaut/example_example.rb +67 -0
  12. data/examples/lib/micronaut/expectations/extensions/object_example.rb +146 -0
  13. data/examples/lib/micronaut/expectations/fail_with_example.rb +17 -0
  14. data/examples/lib/micronaut/expectations/wrap_expectation_example.rb +27 -0
  15. data/examples/lib/micronaut/formatters/base_formatter_example.rb +117 -0
  16. data/examples/lib/micronaut/formatters/documentation_formatter_example.rb +5 -0
  17. data/examples/lib/micronaut/formatters/progress_formatter_example.rb +29 -0
  18. data/examples/lib/micronaut/kernel_extensions_example.rb +13 -0
  19. data/examples/lib/micronaut/matchers/be_close_example.rb +52 -0
  20. data/examples/lib/micronaut/matchers/be_example.rb +298 -0
  21. data/examples/lib/micronaut/matchers/change_example.rb +360 -0
  22. data/examples/lib/micronaut/matchers/description_generation_example.rb +175 -0
  23. data/examples/lib/micronaut/matchers/eql_example.rb +35 -0
  24. data/examples/lib/micronaut/matchers/equal_example.rb +35 -0
  25. data/examples/lib/micronaut/matchers/has_example.rb +69 -0
  26. data/examples/lib/micronaut/matchers/have_example.rb +392 -0
  27. data/examples/lib/micronaut/matchers/include_example.rb +103 -0
  28. data/examples/lib/micronaut/matchers/match_example.rb +43 -0
  29. data/examples/lib/micronaut/matchers/matcher_methods_example.rb +78 -0
  30. data/examples/lib/micronaut/matchers/operator_matcher_example.rb +193 -0
  31. data/examples/lib/micronaut/matchers/raise_error_example.rb +348 -0
  32. data/examples/lib/micronaut/matchers/respond_to_example.rb +54 -0
  33. data/examples/lib/micronaut/matchers/satisfy_example.rb +36 -0
  34. data/examples/lib/micronaut/matchers/simple_matcher_example.rb +93 -0
  35. data/examples/lib/micronaut/matchers/throw_symbol_example.rb +125 -0
  36. data/examples/lib/micronaut/mocha_example.rb +29 -0
  37. data/examples/lib/micronaut/runner_example.rb +41 -0
  38. data/examples/lib/micronaut/world_example.rb +98 -0
  39. data/examples/lib/micronaut_example.rb +43 -0
  40. data/examples/resources/example_classes.rb +67 -0
  41. data/lib/micronaut.rb +40 -0
  42. data/lib/micronaut/behaviour.rb +217 -0
  43. data/lib/micronaut/configuration.rb +162 -0
  44. data/lib/micronaut/example.rb +112 -0
  45. data/lib/micronaut/expectations.rb +45 -0
  46. data/lib/micronaut/expectations/extensions/object.rb +92 -0
  47. data/lib/micronaut/expectations/handler.rb +51 -0
  48. data/lib/micronaut/expectations/wrap_expectation.rb +52 -0
  49. data/lib/micronaut/formatters.rb +12 -0
  50. data/lib/micronaut/formatters/base_formatter.rb +127 -0
  51. data/lib/micronaut/formatters/base_text_formatter.rb +139 -0
  52. data/lib/micronaut/formatters/documentation_formatter.rb +78 -0
  53. data/lib/micronaut/formatters/progress_formatter.rb +30 -0
  54. data/lib/micronaut/kernel_extensions.rb +11 -0
  55. data/lib/micronaut/matchers.rb +141 -0
  56. data/lib/micronaut/matchers/be.rb +204 -0
  57. data/lib/micronaut/matchers/be_close.rb +37 -0
  58. data/lib/micronaut/matchers/change.rb +148 -0
  59. data/lib/micronaut/matchers/eql.rb +26 -0
  60. data/lib/micronaut/matchers/equal.rb +26 -0
  61. data/lib/micronaut/matchers/generated_descriptions.rb +36 -0
  62. data/lib/micronaut/matchers/has.rb +19 -0
  63. data/lib/micronaut/matchers/have.rb +153 -0
  64. data/lib/micronaut/matchers/include.rb +80 -0
  65. data/lib/micronaut/matchers/match.rb +22 -0
  66. data/lib/micronaut/matchers/method_missing.rb +9 -0
  67. data/lib/micronaut/matchers/operator_matcher.rb +50 -0
  68. data/lib/micronaut/matchers/raise_error.rb +128 -0
  69. data/lib/micronaut/matchers/respond_to.rb +50 -0
  70. data/lib/micronaut/matchers/satisfy.rb +50 -0
  71. data/lib/micronaut/matchers/simple_matcher.rb +135 -0
  72. data/lib/micronaut/matchers/throw_symbol.rb +108 -0
  73. data/lib/micronaut/mocking/with_absolutely_nothing.rb +11 -0
  74. data/lib/micronaut/mocking/with_mocha.rb +15 -0
  75. data/lib/micronaut/mocking/with_rr.rb +24 -0
  76. data/lib/micronaut/rake_task.rb +84 -0
  77. data/lib/micronaut/runner.rb +60 -0
  78. data/lib/micronaut/world.rb +75 -0
  79. metadata +165 -0
@@ -0,0 +1,43 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../example_helper")
2
+
3
+ describe Micronaut do
4
+
5
+ describe "#configuration" do
6
+
7
+ it "should return an instance of Micronaut::Configuration" do
8
+ Micronaut.configuration.should be_an_instance_of(Micronaut::Configuration)
9
+ end
10
+
11
+ end
12
+
13
+ describe "#configure" do
14
+
15
+ it "should yield the current configuration" do
16
+ Micronaut.configure do |config|
17
+ config.should == Micronaut.configuration
18
+ end
19
+ end
20
+
21
+ it "should be callable without a block" do
22
+ Micronaut.configure
23
+ end
24
+
25
+ end
26
+
27
+ describe "#world" do
28
+
29
+ it "should return the Micronaut::World instance the current run is using" do
30
+ Micronaut.world.should be_instance_of(Micronaut::World)
31
+ end
32
+
33
+ end
34
+
35
+ describe "InstallDirectory" do
36
+
37
+ it "should be the expanded version of the install directory" do
38
+ Micronaut::InstallDirectory.should == File.expand_path(File.dirname(__FILE__) + "/../../lib")
39
+ end
40
+
41
+ end
42
+
43
+ end
@@ -0,0 +1,67 @@
1
+ # This file contains various classes used by the specs.
2
+ module Micronaut
3
+ module Expectations
4
+ class Person
5
+ attr_reader :name
6
+ def initialize name
7
+ @name = name
8
+ end
9
+ def == other
10
+ return @name == other.name
11
+ end
12
+ end
13
+
14
+ class ClassWithMultiWordPredicate
15
+ def multi_word_predicate?
16
+ true
17
+ end
18
+ end
19
+
20
+ module Helper
21
+ class CollectionWithSizeMethod
22
+ def initialize; @list = []; end
23
+ def size; @list.size; end
24
+ def push(item); @list.push(item); end
25
+ end
26
+
27
+ class CollectionWithLengthMethod
28
+ def initialize; @list = []; end
29
+ def length; @list.size; end
30
+ def push(item); @list.push(item); end
31
+ end
32
+
33
+ class CollectionOwner
34
+ attr_reader :items_in_collection_with_size_method, :items_in_collection_with_length_method
35
+
36
+ def initialize
37
+ @items_in_collection_with_size_method = CollectionWithSizeMethod.new
38
+ @items_in_collection_with_length_method = CollectionWithLengthMethod.new
39
+ end
40
+
41
+ def add_to_collection_with_size_method(item)
42
+ @items_in_collection_with_size_method.push(item)
43
+ end
44
+
45
+ def add_to_collection_with_length_method(item)
46
+ @items_in_collection_with_length_method.push(item)
47
+ end
48
+
49
+ def items_for(arg)
50
+ return [1, 2, 3] if arg == 'a'
51
+ [1]
52
+ end
53
+
54
+ def items
55
+ @items_in_collection_with_size_method
56
+ end
57
+ end
58
+
59
+ class ClassWithUnqueriedPredicate
60
+ attr_accessor :foo
61
+ def initialize(foo)
62
+ @foo = foo
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,40 @@
1
+ require 'micronaut/mocking/with_absolutely_nothing'
2
+ require 'micronaut/matchers'
3
+ require 'micronaut/expectations'
4
+ require 'micronaut/world'
5
+ require 'micronaut/configuration'
6
+ require 'micronaut/runner'
7
+ require 'micronaut/example'
8
+ require 'micronaut/behaviour'
9
+ require 'micronaut/kernel_extensions'
10
+ require 'micronaut/formatters'
11
+
12
+ module Micronaut
13
+ file = if RUBY_VERSION =~ /^1\.9/ then # bt's expanded, but __FILE__ isn't :(
14
+ File.expand_path __FILE__
15
+ elsif __FILE__ =~ /^[^\.]/ then # assume both relative
16
+ require 'pathname'
17
+ pwd = Pathname.new(Dir.pwd)
18
+ path_name = Pathname.new(File.expand_path(__FILE__))
19
+ path_name = File.join(".", path_name.relative_path_from(pwd)) unless path_name.relative?
20
+ path_name.to_s
21
+ else # assume both are expanded
22
+ __FILE__
23
+ end
24
+
25
+ # './lib' in project dir, or '/usr/local/blahblah' if installed
26
+ InstallDirectory = File.expand_path(File.dirname(File.dirname(file)) + "/lib")
27
+
28
+ def self.configuration
29
+ @configuration ||= Micronaut::Configuration.new
30
+ end
31
+
32
+ def self.configure
33
+ yield configuration if block_given?
34
+ end
35
+
36
+ def self.world
37
+ @world ||= Micronaut::World.new
38
+ end
39
+
40
+ end
@@ -0,0 +1,217 @@
1
+ module Micronaut
2
+ class Behaviour
3
+ include Micronaut::Matchers
4
+
5
+ attr_accessor :running_example, :reporter
6
+
7
+ def self.inherited(klass)
8
+ super
9
+ Micronaut.configuration.autorun!
10
+ Micronaut.world.behaviours << klass
11
+ end
12
+
13
+ def self.extended_modules #:nodoc:
14
+ ancestors = class << self; ancestors end
15
+ ancestors.select { |mod| mod.class == Module } - [ Object, Kernel ]
16
+ end
17
+
18
+ def self.befores
19
+ @_befores ||= { :all => [], :each => [] }
20
+ end
21
+
22
+ def self.before_eachs
23
+ befores[:each]
24
+ end
25
+
26
+ def self.before_alls
27
+ befores[:all]
28
+ end
29
+
30
+ def self.before(type=:each, &block)
31
+ befores[type] << block
32
+ end
33
+
34
+ def self.afters
35
+ @_afters ||= { :all => [], :each => [] }
36
+ end
37
+
38
+ def self.after_eachs
39
+ afters[:each]
40
+ end
41
+
42
+ def self.after_alls
43
+ afters[:all]
44
+ end
45
+
46
+ def self.after(type=:each, &block)
47
+ afters[type] << block
48
+ end
49
+
50
+ def self.example(desc=nil, options={}, &block)
51
+ examples << Micronaut::Example.new(self, desc, options.update(:caller => caller[0]), block)
52
+ end
53
+
54
+ def self.alias_example_to(new_alias, extra_options={})
55
+ new_alias = <<-END_RUBY
56
+ def self.#{new_alias}(desc=nil, options={}, &block)
57
+ updated_options = options.update(:caller => caller[0])
58
+ updated_options.update(#{extra_options.inspect})
59
+ block = nil if updated_options[:pending] == true || updated_options[:disabled] == true
60
+ examples << Micronaut::Example.new(self, desc, updated_options, block)
61
+ end
62
+ END_RUBY
63
+ module_eval(new_alias, __FILE__, __LINE__)
64
+ end
65
+
66
+ alias_example_to :it
67
+ alias_example_to :focused, :focused => true
68
+ alias_example_to :disabled, :disabled => true
69
+ alias_example_to :pending, :pending => true
70
+
71
+ def self.examples
72
+ @_examples ||= []
73
+ end
74
+
75
+ def self.examples_to_run
76
+ @_examples_to_run ||= []
77
+ end
78
+
79
+ def self.set_it_up(*args)
80
+ @metadata = { }
81
+ extra_metadata = args.last.is_a?(Hash) ? args.pop : {}
82
+ extra_metadata.delete(:behaviour) # Remove it when present to prevent it clobbering the one we setup
83
+ @metadata.update(self.superclass.metadata)
84
+ @metadata[:behaviour] = {}
85
+ @metadata[:behaviour][:describes] = args.shift unless args.first.is_a?(String)
86
+ @metadata[:behaviour][:describes] ||= self.superclass.metadata && self.superclass.metadata[:behaviour][:describes]
87
+ @metadata[:behaviour][:description] = args.shift || ''
88
+ @metadata[:behaviour][:name] = "#{describes} #{description}".strip
89
+ @metadata[:behaviour][:block] = extra_metadata.delete(:behaviour_block)
90
+ @metadata[:behaviour][:caller] = extra_metadata.delete(:caller) || caller(1)
91
+ @metadata[:behaviour][:file_path] = extra_metadata.delete(:file_path) || @metadata[:behaviour][:caller][4].split(":")[0].strip
92
+ @metadata[:behaviour][:line_number] = extra_metadata.delete(:line_number) || @metadata[:behaviour][:caller][4].split(":")[1].to_i
93
+
94
+ @metadata.update(extra_metadata)
95
+
96
+ Micronaut.configuration.find_modules(self).each do |include_or_extend, mod, opts|
97
+ if include_or_extend == :extend
98
+ Micronaut.configuration.trace { "Extending module #{mod} on #{self}" }
99
+ send(:extend, mod) unless extended_modules.include?(mod)
100
+ else
101
+ Micronaut.configuration.trace { "Including module #{mod} on #{self}" }
102
+ send(:include, mod) unless included_modules.include?(mod)
103
+ end
104
+ end
105
+ end
106
+
107
+ def self.metadata
108
+ @metadata ||= { :behaviour => {} }
109
+ end
110
+
111
+ def self.name(friendly=true)
112
+ friendly ? metadata[:behaviour][:name] : super()
113
+ end
114
+
115
+ def self.describes
116
+ metadata[:behaviour][:describes]
117
+ end
118
+
119
+ def self.description
120
+ metadata[:behaviour][:description]
121
+ end
122
+
123
+ def self.file_path
124
+ metadata[:behaviour][:file_path]
125
+ end
126
+
127
+ def self.describe(*args, &behaviour_block)
128
+ raise(ArgumentError, "No arguments given. You must a least supply a type or description") if args.empty?
129
+ raise(ArgumentError, "You must supply a block when calling describe") if behaviour_block.nil?
130
+
131
+ subclass('NestedLevel') do
132
+ args << {} unless args.last.is_a?(Hash)
133
+ args.last.update(:behaviour_block => behaviour_block)
134
+ set_it_up(*args)
135
+ module_eval(&behaviour_block)
136
+ end
137
+ end
138
+
139
+ def self.ancestors(superclass_last=false)
140
+ classes = []
141
+ current_class = self
142
+
143
+ while current_class < Micronaut::Behaviour
144
+ superclass_last ? classes << current_class : classes.unshift(current_class)
145
+ current_class = current_class.superclass
146
+ end
147
+
148
+ classes
149
+ end
150
+
151
+ def self.before_ancestors
152
+ @_before_ancestors ||= ancestors
153
+ end
154
+
155
+ def self.after_ancestors
156
+ @_after_ancestors ||= ancestors(true)
157
+ end
158
+
159
+ def self.before_all_ivars
160
+ @before_all_ivars ||= {}
161
+ end
162
+
163
+ def self.eval_before_alls(running_behaviour)
164
+ superclass.before_all_ivars.each { |ivar, val| running_behaviour.instance_variable_set(ivar, val) }
165
+ Micronaut.configuration.find_before_or_after(:before, :all, self).each { |blk| running_behaviour.instance_eval(&blk) }
166
+
167
+ before_alls.each { |blk| running_behaviour.instance_eval(&blk) }
168
+ running_behaviour.instance_variables.each { |ivar| before_all_ivars[ivar] = running_behaviour.instance_variable_get(ivar) }
169
+ end
170
+
171
+ def self.eval_before_eachs(running_behaviour)
172
+ Micronaut.configuration.find_before_or_after(:before, :each, self).each { |blk| running_behaviour.instance_eval(&blk) }
173
+ before_ancestors.each { |ancestor| ancestor.before_eachs.each { |blk| running_behaviour.instance_eval(&blk) } }
174
+ end
175
+
176
+ def self.eval_after_alls(running_behaviour)
177
+ after_alls.each { |blk| running_behaviour.instance_eval(&blk) }
178
+ Micronaut.configuration.find_before_or_after(:after, :all, self).each { |blk| running_behaviour.instance_eval(&blk) }
179
+ before_all_ivars.keys.each { |ivar| before_all_ivars[ivar] = running_behaviour.instance_variable_get(ivar) }
180
+ end
181
+
182
+ def self.eval_after_eachs(running_behaviour)
183
+ after_ancestors.each { |ancestor| ancestor.after_eachs.each { |blk| running_behaviour.instance_eval(&blk) } }
184
+ Micronaut.configuration.find_before_or_after(:after, :each, self).each { |blk| running_behaviour.instance_eval(&blk) }
185
+ end
186
+
187
+ def self.run(reporter)
188
+ behaviour_instance = new
189
+ reporter.add_behaviour(self)
190
+ eval_before_alls(behaviour_instance)
191
+ success = run_examples(behaviour_instance, reporter)
192
+ eval_after_alls(behaviour_instance)
193
+
194
+ success
195
+ end
196
+
197
+ # Runs all examples, returning true only if all of them pass
198
+ def self.run_examples(behaviour_instance, reporter)
199
+ examples_to_run.map { |ex| ex.run(behaviour_instance) }.all?
200
+ end
201
+
202
+ def self.subclass(base_name, &body) # :nodoc:
203
+ @_sub_class_count ||= 0
204
+ @_sub_class_count += 1
205
+ klass = Class.new(self)
206
+ class_name = "#{base_name}_#{@_sub_class_count}"
207
+ const_set(class_name, klass)
208
+ klass.instance_eval(&body)
209
+ klass
210
+ end
211
+
212
+ def self.to_s
213
+ self == Micronaut::Behaviour ? 'Micronaut::Behaviour' : name
214
+ end
215
+
216
+ end
217
+ end
@@ -0,0 +1,162 @@
1
+ module Micronaut
2
+
3
+ class Configuration
4
+ # Regex patterns to scrub backtrace with
5
+ attr_reader :backtrace_clean_patterns
6
+
7
+ # All of the defined before/after blocks setup in the configuration
8
+ attr_reader :before_and_afters
9
+
10
+ # Allows you to control what examples are ran by filtering
11
+ attr_reader :filter
12
+
13
+ # Modules that will be included or extended based on given filters
14
+ attr_reader :include_or_extend_modules
15
+
16
+ # Run all examples if the run is filtered, and no examples were found. Normally this is what you want -
17
+ # when using focused examples for instance. Defaults to true
18
+ attr_accessor :run_all_when_everything_filtered
19
+
20
+ # Enable profiling of example run - defaults to false
21
+ attr_accessor :profile_examples
22
+
23
+ # Enable verbose interal logging of the framework - defaults to false
24
+ attr_accessor :trace
25
+
26
+ attr_reader :mock_framework
27
+
28
+ def initialize
29
+ @backtrace_clean_patterns = [/\/lib\/ruby\//, /bin\/rcov:/, /vendor\/rails/, /bin\/micronaut/, /#{::Micronaut::InstallDirectory}/]
30
+ @run_all_when_everything_filtered = true
31
+ @trace = false
32
+ @profile_examples = false
33
+ @color_enabled = false
34
+ @before_and_afters = { :before => { :each => [], :all => [] }, :after => { :each => [], :all => [] } }
35
+ @include_or_extend_modules = []
36
+ @formatter_to_use = Micronaut::Formatters::ProgressFormatter
37
+ @filter = nil
38
+ mock_with nil unless @mock_framework_established
39
+ end
40
+
41
+ # E.g. alias_example_to :crazy_slow, :speed => 'crazy_slow' defines
42
+ # crazy_slow as an example variant that has the crazy_slow speed option
43
+ def alias_example_to(new_name, extra_options={})
44
+ Micronaut::Behaviour.alias_example_to(new_name, extra_options)
45
+ end
46
+
47
+ def cleaned_from_backtrace?(line)
48
+ @backtrace_clean_patterns.any? { |regex| line =~ regex }
49
+ end
50
+
51
+ def mock_with(make_a_mockery_with=nil)
52
+ @mock_framework_established = true
53
+ @mock_framework = make_a_mockery_with
54
+ mock_framework_class = case make_a_mockery_with.to_s
55
+ when /mocha/i
56
+ require 'micronaut/mocking/with_mocha'
57
+ Micronaut::Mocking::WithMocha
58
+ when /rr/i
59
+ require 'micronaut/mocking/with_rr'
60
+ Micronaut::Mocking::WithRR
61
+ else
62
+ require 'micronaut/mocking/with_absolutely_nothing'
63
+ Micronaut::Mocking::WithAbsolutelyNothing
64
+ end
65
+
66
+ Micronaut::Behaviour.send(:include, mock_framework_class)
67
+ end
68
+
69
+ def autorun!
70
+ Micronaut::Runner.autorun
71
+ end
72
+
73
+ # Turn ANSI on with 'true', or off with 'false'
74
+ def color_enabled=(on_or_off)
75
+ @color_enabled = on_or_off
76
+ end
77
+
78
+ # Output with ANSI color enabled? Defaults to false
79
+ def color_enabled?
80
+ @color_enabled
81
+ end
82
+
83
+ def filter_run(options={})
84
+ @filter = options
85
+ end
86
+
87
+ def run_all_when_everything_filtered?
88
+ @run_all_when_everything_filtered
89
+ end
90
+
91
+ def formatter=(formatter_to_use)
92
+ @formatter_to_use = case formatter_to_use.to_s
93
+ when 'documentation' then Micronaut::Formatters::DocumentationFormatter
94
+ when 'progress' then Micronaut::Formatters::ProgressFormatter
95
+ else raise(ArgumentError, "Formatter '#{formatter_to_use}' unknown - maybe you meant 'documentation' or 'progress'?.")
96
+ end
97
+ end
98
+
99
+ # The formatter all output should use. Defaults to the progress formatter
100
+ def formatter
101
+ @formatter ||= @formatter_to_use.new
102
+ end
103
+
104
+ # Where does output go? For now $stdout
105
+ def output
106
+ $stdout
107
+ end
108
+
109
+ # Output some string for debugging/tracing assistance if trace is enabled
110
+ # The trace string should be sent as a block, which means it will only be interpolated if trace is actually enabled
111
+ # We allow an override here so that trace can be set at lower levels (such as the describe or example level)
112
+ def trace(override = false)
113
+ raise(ArgumentError, "Must yield a block with your string to trace.") unless block_given?
114
+ return unless trace? || override
115
+ puts("[TRACE] #{yield}")
116
+ end
117
+
118
+ def puts(msg)
119
+ output.puts(msg)
120
+ end
121
+
122
+ # If true, Micronaut will provide detailed trace output of its self as it runs.
123
+ # Can be turned on at the global (configuration) level or at the individual behaviour (describe) level.
124
+ def trace?
125
+ @trace == true
126
+ end
127
+
128
+ def include(mod, options={})
129
+ include_or_extend_modules << [:include, mod, options]
130
+ end
131
+
132
+ def extend(mod, options={})
133
+ include_or_extend_modules << [:extend, mod, options]
134
+ end
135
+
136
+ def find_modules(group)
137
+ include_or_extend_modules.select do |include_or_extend, mod, options|
138
+ options.all? do |filter_on, filter|
139
+ Micronaut.world.apply_condition(filter_on, filter, group.metadata)
140
+ end
141
+ end
142
+ end
143
+
144
+ def before(each_or_all=:each, options={}, &block)
145
+ before_and_afters[:before][each_or_all] << [options, block]
146
+ end
147
+
148
+ def after(each_or_all=:each, options={}, &block)
149
+ before_and_afters[:after][each_or_all] << [options, block]
150
+ end
151
+
152
+ def find_before_or_after(desired_before_or_after, desired_each_or_all, group)
153
+ before_and_afters[desired_before_or_after][desired_each_or_all].select do |options, block|
154
+ options.all? do |filter_on, filter|
155
+ Micronaut.world.apply_condition(filter_on, filter, group.metadata)
156
+ end
157
+ end.map { |options, block| block }
158
+ end
159
+
160
+ end
161
+
162
+ end